0

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

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

请求具有以下结构:

Message Header
Request Header
Parameters

响应具有以下结构

Message Header
Response Header
Parameters

我知道 TCP 保证发送的包裹将按照发送的顺序发送。但是,无法假设交付可能需要的时间跨度。

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

  1. 服务器 S 向客户端发送响应(Message Header、Response Header、Parameters 放入流中)
  2. 客户端 C 部分接收消息头(例如 12 的前 4 个字节)
  3. 收到这4个字节后,发生接收超时
  4. 在客户端,抛出适当的异常,接收将停止。
  5. 客户认为包裹无效。

现在的问题是,当客户端尝试接收另一个包时,他可能会收到“旧”响应消息头的最后一部分。从当前处理的事务(发送请求/获取响应)来看,客户端收到垃圾。

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

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

在网络上的所有 TCP 示例中,我从未见过处理此类问题的实现......

先感谢您

4

1 回答 1

1

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

如果他收到任何内容,他收到其余的失败消息。他不能接收其他任何东西,特别是不能在之前或代替之前发送的数据之前接收到后来发送的数据。它是一个可靠的字节流。您可以相应地编码。

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

你无法控制它。如果后面的消息已写入 TCP 套接字发送缓冲区,这就是send()实际所做的,它将被发送,并且没有办法阻止它,除非重置连接。

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

于 2013-08-22T01:56:23.070 回答