0

我正在开发通过 TCP/IP 进行通信的 Android 项目。通信工作在特定的协议上——这个协议是面向消息的。

  1. android设备通过套接字向服务器发送消息
  2. 服务器向安卓设备发送应答消息

这不是问题,但我有几个危险的问题。

我不知道如何解决连接中断(wifi,edge,将wifi更改为edge over open socket,......)和连接超时?如果 android 设备发送 1 条消息并且此时出现连接问题 - 然后 android 设备发送不同的消息(其他请求) - 保证答案将以正确的顺序传递?

我尝试为套接字对象设置超时,但它不起作用。我不知道为什么,但是如果我将超时设置为 5 秒,并且在我发送消息之前关闭了服务器 - 她花了超过 5 秒的时间才发出消息。

我没有在互联网上找到任何关于这个问题的文章。

非常感谢。

4

1 回答 1

0

对于 TCP 套接字,您可以获得超时的方法是使用 select() 或 poll(),在 Android 中,您必须使用 SocketChannel() ( java.nio) 类来处理非阻塞套接字。它们都可以查询特定时段(例如 10 或 20 秒)的套接字,并且可以告诉您它是可写的(您可以使用 send())还是可读的(有数据要读取 recv())。select() 命令还会告诉您套接字是否有错误,很可能是连接断开。当你得到这样的错误时(除了中断信号,这个应该被忽略并重新发出选择),你所能做的就是关闭套接字并用服务器重新打开一个新的,据我所知,没有办法, 来恢复断开的连接,但是,如果您已在协议中实现,则可以在套接字断开时从中断的地方恢复。我不知道你是如何实现协议的,但他们中的大多数在继续发送另一条消息之前需要来自接收方的肯定 ACK(确认)。此外,在建立连接时,客户端应指定它是全新连接还是断开连接并采取相应措施。

这个想法是:

发送方发送一个标头,指定要处理的命令和它在标头之后要发送的数据的长度,接收方接收到标头和数据,一旦处理它,它就会向发送方发送一个响应 ACK 包确认消息的值,如果有必要,可以选择使用一些数据。如果在一段合理的时间之后您没有收到 ACK 数据包,那么您可以再次重新发送相同的数据,直到您收到肯定的 ACK。

可能存在客户端发送消息,服务器接收并处理它的情况,但是当服务器发送肯定的 ACK 数据包时,连接中断并且客户端永远不会收到数据包,因此一旦它再次发送相同的消息重新建立连接。为了避免这种情况,有必要在标头中发送一个消息 ID(每发送一条消息都会递增的 int)来标识它。

我知道这听起来很困难,事实上就是这样。如果连接在同一个网络(Intranet)上,它工作得很好,但是,当通信在 Internet 上时,您可能会遇到很多您无法控制的问题和情况,因此需要一个定义良好的协议,您可以从断开的连接中恢复,并且不会复制事务/消息。

于 2013-06-22T12:40:07.010 回答