对于 TCP 套接字,您可以获得超时的方法是使用 select() 或 poll(),在 Android 中,您必须使用 SocketChannel() ( java.nio) 类来处理非阻塞套接字。它们都可以查询特定时段(例如 10 或 20 秒)的套接字,并且可以告诉您它是可写的(您可以使用 send())还是可读的(有数据要读取 recv())。select() 命令还会告诉您套接字是否有错误,很可能是连接断开。当你得到这样的错误时(除了中断信号,这个应该被忽略并重新发出选择),你所能做的就是关闭套接字并用服务器重新打开一个新的,据我所知,没有办法, 来恢复断开的连接,但是,如果您已在协议中实现,则可以在套接字断开时从中断的地方恢复。我不知道你是如何实现协议的,但他们中的大多数在继续发送另一条消息之前需要来自接收方的肯定 ACK(确认)。此外,在建立连接时,客户端应指定它是全新连接还是断开连接并采取相应措施。
这个想法是:
发送方发送一个标头,指定要处理的命令和它在标头之后要发送的数据的长度,接收方接收到标头和数据,一旦处理它,它就会向发送方发送一个响应 ACK 包确认消息的值,如果有必要,可以选择使用一些数据。如果在一段合理的时间之后您没有收到 ACK 数据包,那么您可以再次重新发送相同的数据,直到您收到肯定的 ACK。
可能存在客户端发送消息,服务器接收并处理它的情况,但是当服务器发送肯定的 ACK 数据包时,连接中断并且客户端永远不会收到数据包,因此一旦它再次发送相同的消息重新建立连接。为了避免这种情况,有必要在标头中发送一个消息 ID(每发送一条消息都会递增的 int)来标识它。
我知道这听起来很困难,事实上就是这样。如果连接在同一个网络(Intranet)上,它工作得很好,但是,当通信在 Internet 上时,您可能会遇到很多您无法控制的问题和情况,因此需要一个定义良好的协议,您可以从断开的连接中恢复,并且不会复制事务/消息。