Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 插座卡在关闭位置\u等待_C_Sockets_Tcp - Fatal编程技术网

C 插座卡在关闭位置\u等待

C 插座卡在关闭位置\u等待,c,sockets,tcp,C,Sockets,Tcp,当我的两个守护进程彼此对话时,我的套接字卡在了近处。在阅读了关于这个主题的不同问题和博客条目之后,我已经确认我正在从双方(发起者和接收者)关闭套接字 模型如下: 发件人: 建立连接、发送数据、等待确认、关闭连接 接收人: 接收连接、读取数据、发送确认、关闭连接 谁能告诉我我做错了什么?注意:我正在使用close()关闭连接。我也尝试过使用关机,但它并没有改变一切。如有任何提示,将不胜感激 编辑: 关闭套接字后不久,接收守护进程将分叉。我曾尝试将文件描述符传递给fork函数,并在子进程中再次显式关

当我的两个守护进程彼此对话时,我的套接字卡在了近处。在阅读了关于这个主题的不同问题和博客条目之后,我已经确认我正在从双方(发起者和接收者)关闭套接字

模型如下:

发件人: 建立连接、发送数据、等待确认、关闭连接

接收人: 接收连接、读取数据、发送确认、关闭连接

谁能告诉我我做错了什么?注意:我正在使用close()关闭连接。我也尝试过使用关机,但它并没有改变一切。如有任何提示,将不胜感激

编辑:
关闭套接字后不久,接收守护进程将分叉。我曾尝试将文件描述符传递给fork函数,并在子进程中再次显式关闭它,但这并没有解决我的问题。分叉是否有其他方式影响此过程?请注意,发送守护进程不会分叉。

当您有一个已打开套接字的应用程序,并且在执行一些发送-接收操作后,它从其对等方接受一个FIN,从该状态开始,它进入关闭等待状态。在显式调用close()之前,它可以永远保持该状态。希望您在close()中实际传递了正确的FD。

根据我(简短)的经验,很可能您关闭了错误的FD,甚至根本没有到达“close”语句。我偶然发现了后一个,第一个线索是我的应用程序变成了一个僵尸,而不是关闭(特别是一个简单的printf,就在close语句让它下地狱之前)


可能值得您花时间检查任务管理器/作业/系统监视器/

在查看wireshark后,我看到最终确认信息说:

“[TCP确认丢失的段][TCP上一段丢失]…”


事实证明,我的问题是由两个守护进程在同一个机器上运行(我们为测试添加了一些东西)引起的。在多个框上重试后,我们不再遇到此问题。

实际上,这些是多线程服务器应用程序中常见的问题 要解决此问题,您可以做两件事:

  • 在插座上使用FD_CLOSEXEC
  • 在套接字上使用setsockopt并设置tcp_keepalive
  • 上述两种解决方案的实现代码在*NIX和Microsoft上可能略有不同。这种差异只是由于语义上的差异

    我建议实施上述两项措施

    但是,如果无法修改代码,则可以使用

    你是说等待时间状态?什么是“卡住”?关键是它们需要几分钟的时间来回收。如果要避免等待,请使用SO_REUSEADDR via
    setsockopt
    。@Duck-被卡住的意思是,我看到其他套接字快速打开和关闭(不再出现在netstat的输出中),但一组连接打开并无限期进入关闭等待状态。我已经看了5分钟左右,他们似乎从来没有关闭。它们现在已经持续了10分钟。我认为他们永远不会离开。@sarnold-不,我是说接近_WAIT@dbeer:CLOSE\u WAIT意味着您没有
    CLOSE()
    i谈论两个守护进程。他们不会停止奔跑,所以我不认为他们会变成僵尸。至于错误的文件描述符,我看不出这怎么可能。代码是:fd=open_socket();发送信息(fd,信息);阅读和回复(fd和ret);关闭(fd);我看不出它有任何改变。正如我在问题中所说的,我显式地调用close()。我不相信我的文件描述符可能是错误的。见我对另一个答案的评论。