代码之家  ›  专栏  ›  技术社区  ›  Joshua

如何等待TCP消息被确认

  •  3
  • Joshua  · 技术社区  · 14 年前

    背景:

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

    基准测试表明,使用已经打开的连接要快很多倍,而不是花大量时间(2.5秒)建立新的连接(加密)。

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

    是否有方法等待发送消息[确认或错误]的系统级结果?

    等待读取,然后获取流的结尾会导致混乱。

    我知道信息可能被分成包。如果知道消息的任何部分被确认,或者全部被确认,这同样适合我的目的。这里有趣的问题是陈旧的连接。

    3 回复  |  直到 9 年前
        1
  •  2
  •   user207421    14 年前

    不幸的是,旧的联系可能 陈腐。

    在这种情况下,你最终会得到一个例外。

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

    不。

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

    困惑于谁?这是代码 工作 处理混乱。如果您得到了一个意外的EOS,对等端已经关闭了连接,或者中间防火墙已经关闭了,在这种情况下,您必须处理它。

    我知道信息可能被破坏了 成包。

    完全无关。你也不能控制它,也不能看到它。您得到的是一个以EOS或异常终止的字节流。

    它会适合我的 目的同样清楚地知道 如果消息的任何部分被确认 或者如果一切都是。

    不可能。ACK只意味着它已经到达了对等机的TCP/IP堆栈。您的应用程序感兴趣的是它是否已经进入对等应用程序,并且只有对等应用程序可以通过应用程序协议级ACK告诉您这一点。TCP/IP ACK在这里没有帮助。

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

    这是一个相当小的问题。您可以在代码中检测到它,并且可以处理它,同上。数据库供应商已经做了几十年了。不是火箭科学,也不需要了解TCP ACK。

        2
  •  0
  •   Len Holgate    14 年前

    TCP堆栈本身不太可能及时告诉您连接是否不再可行(除非它在本地断开并且操作系统可以向堆栈报告本地故障)。由于重新传输超时(请参见 here )无论什么情况下,写操作都会返回一个失败,表明连接断开。当然,从设计上来说,这只是设计与你想做的不一致。

    您可以尝试使用tcp-keep-alives,但imho这些并不真正值得您付出努力,如果可能的话,您最好实现某种形式的应用程序级ack,这样您就可以使应用程序级协议在收到您的数据后立即发送响应。如果您不能这样做,并且您的请求从连接的另一端引发响应,那么您只需根据准备等待响应的时间设置一个计时器,然后假设连接已断开。一旦计时器过期,您将关闭连接并建立新的连接。

    可能是您可以触发新的连接尝试,也可以在旧连接上发送请求,如果在收到旧连接的响应之前新连接可用,则可以在新连接上发送请求并关闭旧连接…当然,这取决于您的应用程序能够处理这类事情。

    最后,如果连接由于不活动而断开,那么您可以在协议中添加应用程序级ping,该协议可以设置为每隔一段时间向a)确保连接活动,b)阻止路由器或防火墙认为连接已断开。

        3
  •  -1
  •   jdehaan    14 年前

    在处理TCP通信的层上,不必费心使用ACK。这是第三层及以下的工作。对于您的协议,总是发出命令/响应请求。无论是成功还是错误,都应作出响应。将不回应解释为成功是危险的,因为中断沟通也可能导致同样的效果。

    我不知道你说的陈腐到底是什么意思。因为TCP是面向连接的协议,所以连接是否存在。因此,我并不完全不明白你有什么麻烦:如果你失去了联系,你必须努力创造一个新的。