TCP套接字:发生超时后“回滚”

时间:2013-08-21 09:43:17

标签: sockets tcp poco

这是关于TCP套接字的一个相当普遍的问题。我有一个客户端/服务器应用程序设置,通过TCP通过线路发送消息。实现是通过C ++ POCO完成的,但问题与某项技术无关。

消息可以是请求(由客户端发起)或响应(由服务器发起)。

请求具有以下结构:

Message Header
Request Header
Parameters

响应具有结构

Message Header
Response Header
Parameters

我知道TCP保证发送的包将按照发送的顺序发送。但是,没有任何关于交付可能需要的时间跨度的假设。

双方都配置了读/发送超时。现在我想知道如何在超时后对传输的数据进行干净的设置。不知道如何用正确的术语表达这一点,所以让我描述一个例子:

  1. 服务器S向客户端发送响应(消息头,响应头,参数放入流中)
  2. 客户端C部分地接收消息头(例如,12的前4个字节)
  3. 收到这4个字节后,发生接收超时
  4. 在客户端,抛出适当的异常,接收将被停止。
  5. 客户认为该包无效。
  6. 现在问题是,当客户端尝试接收另一个包时,他可能会收到“旧”响应消息头的持久部分。从当前处理的事务(发送请求/获取响应)的角度来看,客户端接收垃圾。

    所以似乎在发生超时后(无论是在客户端还是在服务器端),通信都应该继续进行“干净设置”,这意味着没有任何通信伙伴会尝试发送一些旧的包数据,并且没有旧的包数据存储在相应套接字的流缓冲区中。

    那么这种情况通常如何处理?是否有某种设计模式/惯用方法来解决这个问题? 如何在其他基于TCP的协议中处理此类情况,例如HTTP?

    在网络上的所有TCP样本中,我从未见过处理这类问题的实现......

    提前谢谢

1 个答案:

答案 0 :(得分:1)

  

当客户端尝试接收另一个包时,他可能会收到“旧”响应消息标题的持久部分

如果他收到任何内容,他收到其余的失败消息。他无法接收任何其他内容,特别是之前发送的数据无法在之前发送的数据之前或之前收到。它是一个可靠的字节流。你可以相应地编码。

  

通信应继续“干净设置”,这意味着没有任何通信伙伴会尝试发送一些旧的数据包

你无法控制它。如果已将以下消息写入TCP套接字发送缓冲区(即send()实际执行的所有内容),则会发送该消息,并且无法阻止其重置连接。

因此,您需要对客户端进行编码,以便在到达时处理整个字节流,或者在超时时关闭连接并重新开始。