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

uri*_*ium 3 sockets

我使用Java(虽然我认为套接字选项是在大多数语言中实现)来实现客户端和服务器.服务器将数据发送到客户端以进行客户端确认的处理.在另一个端口上,客户端然后将处理结果发送回服务器.说到诸如此类的选项

  • SO_LINGER
  • SO_KEEPALIVE
  • SO_NODELAY
  • SO_REUSEADDRESS
  • SO_SENDBUFFER
  • SO_RECBUFFER
  • TCP_NODELAY

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

根据上述场景设置的最佳选项是什么?我们可以从我们这边做什么(以编程方式或选项方式)来尝试最小化连接被丢弃的次数.我们使用普通的TCP/IP.

更新:对此的赏金很快就结束了.我还没有得到满意的答案,所以它仍然是开放的.我想每个人都错过了这个任务的重点.关于连续聊天的套接字的上述选项的最佳实践是什么?我已经有一个ping数据包,如果没有工作要做(几乎没有情况),正常的消息发送没有内部元素,所以总是处理.

sar*_*old 6

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

* SO_LINGER
Run Code Online (Sandbox Code Playgroud)

SO_LINGER只有当您的应用程序仍然有未完成的数据包要发送close(2)或被shutdown(2)调用时,您才需要进行设置.不适用于您的应用程序.

* SO_KEEPALIVE
Run Code Online (Sandbox Code Playgroud)

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

* SO_NODELAY
Run Code Online (Sandbox Code Playgroud)

这(可能是TCP_NODELAY的别名)禁用了Nagle的算法,这只是一个小包避免问题.也许Nagle会妨碍您的应用程序,但它需要特殊的数据包序列才能在处理过程中引入500毫秒的延迟; 它永远不会挂起连接.

* SO_REUSEADDRESS
Run Code Online (Sandbox Code Playgroud)

适用于侦听众所周知端口号的所有"服务器"; 在'客户'上使用几乎总是掩盖一些错误或其他错误,但如果请求必须来自一个众所周知的端口号,有时是必要的.

* SO_SENDBUFFER
* SO_RECBUFFER
Run Code Online (Sandbox Code Playgroud)

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

* TCP_NODELAY
Run Code Online (Sandbox Code Playgroud)

禁用Nagle.如果您的应用程序在尝试阻塞读取之前发送多个小数据包,则不会引入500ms延迟.

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

你能将你的代码提炼成可以粘贴在这里并进行测试或检查的东西吗?我习惯于TCP会话存活数天或数周没有问题,所以这是非常令人惊讶的.