linux - TCP 套接字挂起 - 双方都卡在 sendto()

标签 linux sockets freeze sendto

我们有一个似乎挂起的 Linux 应用程序(我们没有源代码)。两个进程之间的套接字被报告为已建立,内核套接字缓冲区中有一些数据(虽然远不及通过 wmem/rmem 配置的 16M)。套接字的两端似乎都卡在了 sendto() 上。

下面是一些使用 netstat/lsof 和 strace 的调查:

主机 A (10.152.20.28)

[root@hosta ~]# lsof -n -u df01 | grep 12959 | grep 12u
q         12959 df01   12u  IPv4            4398449                TCP 10.152.20.28:38521->10.152.20.29:gsigatekeeper (ESTABLISHED)

[root@hosta ~]# netstat -anp | grep 38521
tcp   268754  90712 10.152.20.28:38521          10.152.20.29:2119           ESTABLISHED 12959/q

[root@hosta ~]# strace -p 12959
Process 12959 attached - interrupt to quit
sendto(12, "sometext\0somecode\0More\0exJKsss"..., 542, 0, NULL, 0 <unfinished ...>
Process 12959 detached
[root@hosta~]#

主机 B (10.152.20.29)

[root@hostb ~]# netstat -anp | grep 38521
tcp    72858 110472 10.152.20.29:2119           10.152.20.28:38521          ESTABLISHED 25512/q

[root@hostb ~]# lsof -n -u df01 | grep 38521
q         25512 df01   14u  IPv4            6456715                 TCP 10.152.20.29:gsigatekeeper->10.152.20.28:38521 (ESTABLISHED)

[root@hostb ~]# strace -p 25512
Process 25512 attached - interrupt to quit
sendto(14, "\0\10\0\0\0Owner\0sym\0Type\0Ctpy\0Time\0Lo"..., 207, 0, NULL, 0 <unfinished ...>
Process 25512 detached
[root@hostb~]#

我们已将 NIC 驱动程序升级到最新最好的。系统正在运行 RHEL 5.6 x64 (2.6.18-238.el5),我已经检查了 RHEL 5.7 和 5.8 的 eratta,但我没有看到 bnx2 驱动程序或内核的错误。

有没有人知道如何进一步调试它?

最佳答案

任何一方都在阅读吗?如果不是,可能是双方的接收缓冲区都满了,导致不发送数据(由于接收窗口被填满),导致双方的发送缓冲区都被填满,这会导致sendto阻止。 (如果应用程序设置了 SO_RCVBUFSO_SNDBUF 套接字选项,尽管您设置了 wmem/rmem,这也可能发生。)

为了调试它,我会同步两台机器的时钟,然后在 strace 下运行两个应用程序与 -e trace=network-tt选项,因此您可以比较日志并查看应用程序是否未读取。

您还可以使用网络分析器(例如 Wireshark )来确定 TCP 接收窗口是否停留在 0。

如果是这种情况,您可能可以通过创建一个小型缓存代理来解决此问题,该代理将从双方接收/发送,缓冲当时无法发送的内容。

关于linux - TCP 套接字挂起 - 双方都卡在 sendto(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7429438/

相关文章:

linux - 定义多个 struct machine_desc 结构

linux - 想要将命令 echo ^`date` 的结果分配给一个变量。但是当我尝试这样做时,我没有得到异常(exception)的结果

c - 如何避免在 Linux 上的 strftime() 中调用过多的 stat(/etc/localtime)?

python - 使用套接字从 Python(客户端)向 C++(服务器)数组发送数据

mysql - 获取 "Can' t 通过套接字 '/var/run/mysqld/mysqld.sock' 连接到本地 MySQL 服务器“为 Ruby on Rails 应用程序设置 mysql 数据库时出错

iis-7.5 - IIS : Web Application hangs periodically needs system reboot

linux - 当从内核内部调用 open()/socket() 时,文件描述符是如何分配的?

c - 套接字如何处理本地地址更改?

java - 使用 Google 电子表格 API 卡住行并设置样式

Android 应用程序挂起,有时直到出现“强制关闭/等待”对话框