如何等待TCP消息被确认

时间:2010-07-02 21:03:24

标签: tcp winsock packet

背景:

我们有一个客户端/服务器应用程序,它使用与服务器的持久连接。

基准测试显示,使用已打开的连接速度要快很多倍,而不是花费大量时间(2.5秒)设置新连接(加密)。

不幸的是,旧的连接可能是陈旧的。

有没有办法等待发送消息的系统级结果[ACK或错误]?

等待阅读然后结束流会导致混乱。

我知道这条消息可能被分解成数据包。它同样适合我的目的,要么知道消息的任何部分是否被激活,或者是否所有部分都被激活了。这里有趣的问题是陈旧的连接。

3 个答案:

答案 0 :(得分:2)

  

不幸的是,旧的连接可能会   过时了。

在这种情况下,最终写入时会出现异常。

  

有没有办法等待   系统级别的发送结果   消息[ACK或错误]?

没有

  

等待阅读然后获得   流的结束导致混乱。

困惑谁?处理混淆是代码的作业。如果您收到意外的EOS,则对等方已关闭连接,或中间防火墙已关闭,在这种情况下您必须处理它。

  

我知道这条消息可能会被打破   分组。

完全无关紧要。您无法控制它或任何可见性。你得到的是由EOS或异常终止的字节流。

  

这适合我的   目的同样很好   如果消息的任何部分被激活   或者全部都是。

不,不会。 ACK仅表示它已达到对等方的TCP / IP堆栈。您的应用程序感兴趣的是它是否已进入对等应用程序,只有对等应用程序可以通过应用程序协议级别的ACK告诉您。 TCP / IP ACK在这里没有任何帮助。

  

这里有趣的问题是陈旧的连接。

这是一个相当微不足道的问题。您可以在代码中检测它,您可以同样处理它。几十年来,数据库供应商一直在做这些事情。不是火箭科学,也不需要知道TCP ACK。

答案 1 :(得分:0)

如果连接不再可行,TCP堆栈本身不太可能及时告诉您(除非它在本地中断并且操作系统可以向堆栈报告本地故障)。由于重传超时(参见here)以及在写入之前可能需要“相当长的时间”才会返回指示连接断开的失败。当然,这是设计,只是设计与你想做的事情不一致。

您可以尝试使用TCP keep alives但是IMHO这些并不值得付出努力,如果可能的话,您最好实现某种形式的应用程序级别的ACK,以便您可以使您的应用程序级协议发回响应一旦它从你那里得到一些数据。如果您不能这样做,并且您的请求会从连接的另一端引出响应,那么您可以根据您在假设连接已停止之前等待响应的准备时间来设置计时器。计时器到期后,关闭连接并建立新连接。

可能是您可以启动新的连接尝试并在旧连接上发送请求,如果新连接在您从旧连接获得响应之前可用,那么您可以在新连接上发送请求并关闭旧的...当然这依赖于你的应用程序能够处理这种事情。

最后,如果由于不活动而导致连接中断,那么您可以在协议中添加应用程序级ping,可以将其设置为每隔一段时间发送一条消息a)确保连接处于活动状态并且b)停止路由器或防火墙认为连接已经死亡。

答案 2 :(得分:-1)

在您处理TCP通信的层,您不必担心ACK。这是第3层及以下的工作。对于您的协议,请始终发出命令/响应请求。无论成功与否,都应该在那里作出回应。将无响应解释为成功是危险的,因为断开沟通也会产生同样的效果。

我不知道你的陈词滥调是什么意思。因为TCP是面向连接的协议,所以连接是否存在。因此,我不太明白你遇到了什么麻烦:如果你失去联系,你必须努力创建一个新的。