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

连续传输数据的客户端和服务器的最佳套接字选项

  •  3
  • uriDium  · 技术社区  · 15 年前

    我使用Java(尽管我认为socket选项在大多数语言中都是实现的)来实现客户机和服务器。服务器将数据发送到客户端进行处理,客户端对此进行确认。在另一个端口上,客户机然后将处理结果发送回服务器。当涉及到诸如

    • 所以你留恋
    • 所以你要活下去
    • 所以你需要一个缓冲区
    • TCP\U节点

    我们注意到客户端和服务器之间的连接偶尔会中断。发送或接收将超时。当这种情况发生时,将终止套接字并打开一个新的套接字以继续。

    更新:

    6 回复  |  直到 15 年前
        1
  •  7
  •   sarnold    15 年前

    严格来说,您不需要这些套接字选项中的任何一个:

    * SO_LINGER
    

    你需要设置 SO_LINGER 仅当应用程序仍有未完成的数据包要发送时 close(2) shutdown(2) 已调用。不太适合你的申请。

    * SO_KEEPALIVE
    

    每两小时发送一次keepalive ping实际上只会帮助非常长寿命但非常安静的连接通过具有很长会话超时的有状态防火墙(在今天的互联网上,两个小时的ping间隔实在太长了。)

    * SO_NODELAY
    

    这(可能是TCP\u NODELAY的别名)禁用 Nagle's algorithm

    * SO_REUSEADDRESS
    

    适用于所有监听已知端口号的“服务器”;在“客户机”上使用几乎总是掩盖一些bug或其他bug,但如果请求必须来自一个众所周知的端口号,则有时是必要的。

    * SO_SENDBUFFER
    * SO_RECBUFFER
    

    当程序(接收缓冲区)或套接字(发送缓冲区)尚未准备好接受更多数据时,这些缓冲区大小会影响为接收或发送数据而维护的内核端缓冲区大小。如果这些设置太小,应用程序可能无法尽可能平稳地传输数据,从而降低吞吐量,但如果这些设置小于最佳值,则不应导致任何暂停。当然,太大可能会对内核内存提出不合理的要求,但是应该有一个合理的系统范围内允许的最大大小。

    * TCP_NODELAY
    

    实际上,您不需要设置任何套接字选项。

    你能把你的代码提炼成可以粘贴在这里测试或检查的东西吗?我已经习惯了TCP会话可以连续几天或几周不出问题,所以这是非常令人惊讶的。

        2
  •  2
  •   cape1232    15 年前

    首先,我认为这一页是相关的,关于半开放的连接。 http://nitoprograms.blogspot.com/2009/05/detection-of-half-open-dropped.html

    因为您编写的是客户机和服务器,所以我避免依赖TCP来告诉您连接何时完全中断。我只想让服务器也确认从客户端收到的结果。然后双方都会期望对他们的消息立即做出响应,您可以跟踪哪些消息已经确认,并为接收确认设置一个适当的小超时。这不是发送或接收的超时,而是发送消息和接收该消息的ack之间的超时。然后,您可以根据连接的质量适当地设置超时(例如,如果在环回上运行,则超时很小;如果在无线上运行且信号较弱,则超时很大)。

    关于您列出的选项,您将希望使用SO\u REUSEADDRESS,这样就不会阻止您重新打开套接字,例如,如果它还没有完成从先前终止的进程关闭的操作。

        3
  •  1
  •   Jon    15 年前

    你可能有,但最好检查明显的。。。。

    您是否验证了是套接字超时,而不是您的代码超时?套接字是相当稳定的,虽然某个地方可能有问题,但它更可能出现在您的代码中。我会使用日志、时间戳和同步时钟来确定。

    可能有一个问题,你真的花了很长时间来做计算,所以也许添加一个'我还在想它'的消息到您的协议,定期发送,以保持连接活着?

    当然,不管你做什么,网络都会时不时地退出,听起来你已经很好地处理了这个案子。

        4
  •  0
  •   Dharma    15 年前

    尝试以下选项 sou LINGER-用于在队列中调用一些未发送的数据时,在套接字关闭时进行指定 TCP\U NODELAY-用于非阻塞数据传输

        5
  •  0
  •   weismat    15 年前

    我强烈建议您在客户机和服务器之间使用ping/echo模型,这样,如果x秒内没有数据发送,就需要发送ping消息。中断的一个典型原因可能是防火墙,它会因为不活动而关闭sockets。

        6
  •  0
  •   sarnold    15 年前

    连接通过NAT防火墙的可能性有多大?有状态防火墙维护一个开放连接表,以便属于允许连接的数据包可以快速通过系统,而无需强制防火墙管理员编写过于复杂的规则集。

    缺点是,这个表可能会变得非常大,因此必须在连接关闭或它们看起来只是过时并悄然消亡时对其进行修剪。一个沉默了20分钟的连接通常是安静到可以收获的(这真的很快,就像TCP KEEPALIVE 通常是两个小时,在NAT防火墙面前几乎毫无用处。)

    所以:这是通过NAT防火墙吗?连接是否长时间保持安静?如果是这样,在协议中添加一个ping/pong,并每隔几分钟启动一次。

    推荐文章