问题描述
当通过 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 (将#修改为@)