首页 > 解决方案 > 使用 tcp/ip 时处理异常

问题描述

下面是一个工作应用程序的片段:

import net

class TcpReceiver :
  task_     := null
  
  constructor _port:
    task_ = task:: receiveTcp _port
 
  receiveTcp listenPort :
    network_interface := net.open
    while true :
      waitingTcpMessage network_interface listenPort
    print "<<<<<<< receiveTcp EXIT >>>>>>>"  

sendMessage interface clientAddress/string port/int text/string :
  clientSocket :=  interface.tcp_connect clientAddress port
  clientSocket.write "$clientAddress:$text"
  clientSocket.close

waitingTcpMessage interface port/int :
  serverSocket := interface.tcp_listen port
  print ("Waiting for a TCP message ...")
  socket := serverSocket.accept
  data := socket.read
  clientAddr := socket.peer_address.ip.stringify
  print ("[$clientAddr]->[$data.to_string]")
  sendMessage interface clientAddr port "[$data.to_string]"
  serverSocket.close

main :

  TcpReceiver 1234

这是一个非常简单的 tcp/ip 客户端/服务器。它从客户端(在这种情况下,从 android 应用程序)接收消息并将接收到的消息发送回(给客户端)。然而,很明显,网络中的任何操作都与出现的错误相关联,这些错误很容易导致该应用程序瘫痪,并且必须再次运行。例如:

EXCEPTION error. 
Connection closed
  0: tcp_error_                system/modules/tcp.toit:189:3
  1: TcpSocket_.ensure_state_  system/modules/tcp.toit:66:14
  2: TcpSocket.connect         system/modules/tcp.toit:135:5
  3: TcpSocket.connect         system/modules/tcp.toit:130:12
  4: WifiNetworkInterface.tcp_connect system/components/wifi.toit:97:7
  5: NetworkInterfaceResource.tcp_connect system/components/network.toit:91:26
  6: register_network.<lambda> system/components/network.toit:26:23
  7: RpcBroker.get_handler_.<block>.<lambda> system/kernel/rpc.toit:74:17
  8: RpcBroker.listen_.<lambda>.<block> system/kernel/rpc.toit:107:29
  9: catch.<block>             <sdk>/core/exceptions.toit:111:10
 10: catch                     <sdk>/core/exceptions.toit:109:1
 11: catch                     <sdk>/core/exceptions.toit:84:10
 12: RpcBroker.listen_.<lambda> system/kernel/rpc.toit:106:9
 13: TaskCache_.broker_task_   <sdk>/monitor.toit:430:14
 14: TaskCache_.run.<block>.<lambda> <sdk>/monitor.toit:426:42

处理此类错误的最简单方法是使用try..catch..finally之类的结构。但是为此,您至少需要知道哪些函数能够引发异常。在这种情况下,只有两个这样的操作是显而易见的:socket.readsocket.write。它们可以用try..finally包裹起来,没问题。但问题仍然存在:这些是唯一需要这种保护的操作,还是还有其他操作?最安全的 tcp/ip 客户端/服务器在 TOIT 上应该是什么样子(即使像这里这样的功能最少)?

提前感谢您的回答,MK。

标签: exceptionservertcpclienttoit

解决方案


推荐阅读