选择系统调用在/ w应用程序中无限期挂起.

ern*_*sto 4 sockets linux network-programming

我们有一个网络应用程序,它将在各种脚本中用于与其他系统进行通信.

有时,脚本会挂起对我们网络应用程序的调用.我们最近遇到了挂起,我试图调试这个特定应用程序的挂起过程.

此应用程序由客户端和服务器(守护程序)组成,挂起发生在客户端.

Strace输出显示它挂在选择系统调用上.

> strace -p 34567
select(4, [3], NULL, NULL, NULL
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在select调用中没有给出超时,如果文件描述符"3"未准备好读取,它可以无限期地阻塞.

lsof输出显示fd'3'处于FIN_WAIT2状态.

> lsof -p 34567
client  34567 user 3u  IPv4 55184032 TCP client-box:smar-se-port2->server:daemon (FIN_WAIT2)
Run Code Online (Sandbox Code Playgroud)

以上信息是否意味着什么?FIN_WAIT2状态?我检查了服务器端(应该运行相应的守护程序进程),但是服务器端没有运行守护程序进程.我的猜测是守护进程成功运行并将输出发送到客户端,这应该在fd'3'上可用于读取,但客户端上的select()调用永远不会出现,仍然等待发生的事情!

我不确定为什么它永远不会出现select()调用,这只会偶尔发生,大多数情况下应用程序才能正常工作.

有线索吗?

服务器和客户端都是SuSE Linux.

Rem*_*eau 5

FIN_WAIT2表示您的应用已将FIN数据包发送给对等方,但尚未收到FIN来自对等方的数据包.在TCP中,优雅的结束需要FIN来自双方.服务器守护程序未运行的事实意味着守护程序退出(或被杀死)而不通知其对等方(您).因此,您select()正在等待它将不再接收的数据包,并且必须等待操作系统使用内部超时使套接字无效,这可能需要很长时间.这是为什么你永远不应该使用无限超时的情况.如果超时,则使用适当的超时并相应地执行操作.