我正在研究通过TCP / IP进行通信的Android项目。通信适用于特定协议 - 该协议是面向消息的。
这不是问题,但我有一些棘手的问题。
我不知道如何解决连接中断(wifi,边缘,将wifi改为打开套接字边缘,...)和连接超时?如果android设备发送1条消息并且此时是连接问题 - 那么android设备发送不同的消息(其他请求) - 保证答案将以正确的顺序传递?
我尝试为套接字对象设置超时但它不起作用。我不知道为什么,但是如果我将超时设置为5秒并且在发送消息之前我关闭了服务器 - 在她来辅料之前花了超过5秒钟。
我没有在互联网上找到任何关于这个问题的文章。
非常感谢。
答案 0 :(得分:0)
对于TCP套接字,您可以通过使用select()或poll()获得超时,在Android中您必须使用SocketChannel()(java.nio)类来处理非阻塞套接字。它们都可以查询特定时间段(例如10或20秒)的套接字,并且可以告诉您它是否可写(可以使用send())或可读(有数据要读取recv())。 select()命令也会告诉您套接字是否有错误,很可能是连接断开。当你遇到这样的错误时(除了中断的信号,这个应该被忽略并重新发出选择),你所能做的就是关闭套接字并用服务器重新打开一个新的,就我所知,没有办法,以恢复断开的连接,但是,如果您已在协议中实现,则可以在套接字断开时从中断处继续。我不知道你是如何实现协议的,但是在继续使用另一条消息之前,大多数都需要来自接收方的肯定ACK(确认)。此外,在建立连接时,客户应指定是全新连接还是破坏连接并采取相应措施。
这个想法是:
发送方发送一个标头,指定要处理的命令以及它将在标头之后发送的数据长度,接收方接收标头和数据,一旦处理完毕,它就会向发送方发送响应ACK数据包具有正值以确认消息,可选地在必要时具有一些数据。如果在一段合理的时间之后您没有收到ACK数据包,那么您可能会再次重新发送相同的数据,直到您收到肯定的ACK。
可能存在客户端发送消息,服务器接收并处理它的情况,但是当服务器发送肯定ACK数据包时连接中断并且客户端从不接收数据包,因此它将重新发送相同的消息一旦连接重新建立,再次。为避免这种情况,有必要在标题中发送消息ID(对于发送的每个消息递增的int)以识别它。
我知道这听起来很难,事实上。如果连接在同一个网络(内联网)上,它可以很好地工作,但是当通信在互联网上时,你可能会遇到许多你无法控制的问题和情况,所以你需要一个定义良好的协议。从断开的连接中恢复,交易/消息不会重复。