TCP 写操作在非阻塞模式下有时会阻塞超过几毫秒

问题描述

当通过 TCP 从客户端到服务器传输数据时,我遇到了一个奇怪的阻塞问题。
我的客户端以 non-blocking 模式打开一个 TCP 套接字。
大多数情况下,一切正常,write 调用会立即返回 (500-700 usec)。
但有时,write 方法被阻塞了几次连续的 write 调用,然后恢复正常(write 调用立即返回 (500-700 usec))。

有一次出现问题时,我注意到我需要写入的数据的大小为 1324752 bytes,而待处理的数据(我为此使用了 ioctl(c->fd,SIOCOUTQ,&pending))在TCP 套接字队列是 331188 bytes,然后 write 调用被阻塞 0.9 msec
在下一次写入时,我需要写入的数据大小为 1249300 bytes,而 TCP 套接字队列中的待处理数据为 330144 bytes,然后 write 调用被阻塞 {{ 1}}。 以下写入操作也花了几毫秒(13 毫秒和 4 毫秒),然后事情开始冷却并恢复正常...
我将尝试将其总结为一个表格:

  • 序列号 2269863 是此跟踪中的第一个写入操作(2269864 是第二个操作等)
  • 数据大小是我们需要发送的数据大小。
  • nwritten 是我们成功发送的实际数据。
  • pending data 是套接字发送队列中未发送的数据量。
  • 写入持续时间是写入操作被阻塞的时间。
序列号 数据大小[字节] nwritten [bytes] 待处理数据[字节] 写入时长 [usec]
2269863 1324752 225992 331188 934
2269864 1249300 718431 330144 22227
2269865 651301 651301 0 13648
2269866 150540 150540 0 4262
2269867 30108 30108 0 755
2269868 30108 30108 0 754
2269869 30108 30108 0 613
2269870 30108 30108 0 857
2269871 30108 30108 0 555
2269872 30108 30108 0 569
2269873 30108 30108 0 636
2269874 30108 30108 0 814
2269875 30108 30108 0 812

一些重要的注意事项:

  • 我已确认已设置 NON_BLOCKING 标志。
  • 我正在运行 6 个 TCP 客户端,将它们的数据发送到同一个 TCP 服务器 - 当写入方法被阻止时,它会同时发生在大多数客户端上(有时在所有客户端上)。
  • 服务器在 linux 4.15 上运行,客户端在 linux 4.19 上运行。

问题:
为什么写阻塞这么长时间(是否配置为非阻塞操作)?

欢迎提供任何提示或想法,
谢谢!!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)