使用TCP套接字(C#),如何检测接收方在传输过程中是否中断了消息?

3
我正在为我的iPhone应用编写服务器应用程序。我正在处理的部分是中继服务器。这个服务器通过TCP套接字在iPhone之间中继消息。服务器从流中读取头的长度,然后从流中读取相应数量的字节。它反序列化头,并检查消息是否需要中继到另一个iPhone(而不是在服务器上处理)。
如果需要中继,则开始从发送者的套接字中每次读取1024字节。在接收到每1024字节后,它将这些字节(作为字节“数据包”)添加到传出消息队列中,按顺序处理。
这一切都很好,但是如果发送者被中断了怎么办(例如,在发送3,000字节中的2,500字节后,发送者的iPhone进入了隧道)?
这意味着所有其他设备都在等待剩余的500字节,但这些字节没有被中继给他们。然后,如果发送者(或其他任何人)向这些套接字发送数据,它们会认为新消息的开头是上一个消息的结尾,从而破坏数据。
显然,根据上述描述,我正在使用消息分帧,但我认为我漏掉了什么。从我所看到的,消息分帧似乎只允许接收者知道从套接字中读取的确切字节数,然后将它们组装成一个对象。一旦有一个或两个字节走失,会不会让一切都变得混乱?是否有一种标准方法可以重新同步?

这似乎更适合使用UDP来处理数据包中继,因为您不希望受到单个连接的流量控制延迟的影响。 - Sedat Kapanoglu
我理解你的观点,但我的整个网络层是TCP,而TCP对于这个任务来说是理想的,只是中继部分似乎不太适合设计。我在想是否有什么简单的东西被我忽略了。 - Dermot
如果发生上述情况,我想我会在中继服务器端放弃套接字。这将清除缓冲区,客户设备将在断开连接时自动重新连接套接字。 - Dermot
1个回答

3
一旦一个或两个字节出现偏差,是否会使一切失去同步?有没有标准的方法可以重新同步?
TCP/IP本身确保单个套接字连接中没有字节丢失。
在您的情况下,情况要复杂一些,因为(如果我理解正确)您正在使用服务器作为一种多路复用器。
在这种情况下,以下是我能想到的一些选项:
1.让服务器在从A点缓冲整个消息后再将其发送到B点。
2.如果从A端检测到异常关闭,则关闭B端套接字。
3.更改协议的接收端,使B端客户端能够检测和恢复部分A流而无需杀死和重新建立套接字。例如,如果服务器为每个传入的A流提供了唯一的ID,则B客户端将能够检测到不同的流是否开始。或者添加额外的长度前缀,以便B客户端知道要期望的整个长度和该个体消息的长度。
选择哪个选项取决于您正在传输的数据类型以及不同部分的易于更改程度。
无论使用哪种解决方案,一定要包括半开连接的检测

我可能会选择第二个选项,关闭B端插座。我更喜欢避免先缓冲整个消息,因为我们的想法是每次中继1024字节可以减少服务器中继时的内存需求。感谢您提供有关半开放连接的提示。 - Dermot
链接失效,这个链接似乎可行:http://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html - g t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接