免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3857 | 回复: 11
打印 上一主题 下一主题

★请教:fork进程遇到端口状态不释放的问题★ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-08 15:45 |只看该作者 |正序浏览
气死我了!!!!刚写完了帖子!!!!!脚碰到了电源!!!!!!

重写!!!!!!!!!疯了我!!!!

废话少说,请教大家:

写了一个C/S程序,简单介绍一下:Server在6666端口监听(使用netstat可以看到6666端口状态为LISTEN),准备接收来自Client的命令,当收到Client的“启动”命令时,Server fork()一个进程,execlp()另一个程序AAA,该AAA程序内为循环,一直运行,此时使用netstat可以看到6666端口增加一个状态为CLOSE_WAIT,此时Client依然可以向Server发送其他命令。只有当Client发送“停止AAA”的命令或者手动结束AAA进程时,该CLOSE_WAIT状态才消失。

之所以为这个问题苦恼,是因为:如果AAA在运行过程中,server被错误终止,则该CLOSE_WAIT将一直存在下去,尽管Server的进程已经不存在。此时再结束AAA,也无济于事。重启Server后,因为CLOSE_WAIT状态一直存在,Server将无法接收来自Client的命令,且Client连接Server:6666一次,Server便增加一个CLOSE_WAIT状态。我在多个UNIX平台(sun/hp/aix等)上都试过,这种CLOSE_WAIT状态不会自己关闭。所以每次都很痛苦,需要重启网卡。要么就重启系统。

请各位不吝赐教:
1、为什么fork一个进程便会产生一个CLOSE_WAIT状态?
2、并且这种状态必须随着子进程的终止才能结束?
3、有没有方法避免或者解决这种CLOSE_WAIT的方法?

我曾经尝试向6666端口发送RST标志位=1或者FIN=1的TCP包,也不能reset这个连接。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
12 [报告]
发表于 2003-07-10 13:36 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

了一个C/S程序,简单介绍一下:Server在6666端口监听(使用netstat可以看到6666端口状态为LISTEN),准备接收来自Client的命令,当收到Client的“启动”命令时,Server fork()一个进程,execlp()另一个程序AAA,该AAA程序内为循环,一直运行,此时使用netstat可以看到6666端口增加一个状态为CLOSE_WAIT,此时Client依然可以向Server发送其他命令。只有当Client发送“停止AAA”的命令或者手动结束AAA进程时,该CLOSE_WAIT状态才消失。

【遇到类似的问题的时候,解决的办法很简单,你用netstat -a|grep 6666看看,出现close_wait状态的是拿一个端点,这样就知道是那个进程执行了close操作或者进程异常】

之所以为这个问题苦恼,是因为:如果AAA在运行过程中,server被错误终止,则该CLOSE_WAIT将一直存在下去,尽管Server的进程已经不存在。

【很明显,你的描述是因为server执行了close引起的,因为aaa仍然在运行,因此出现在aaa这端的tcp状态一直在维持着】

此时再结束AAA,也无济于事。重启Server后,因为CLOSE_WAIT状态一直存在,Server将无法接收来自Client的命令,且Client连接Server:6666一次,Server便增加一个CLOSE_WAIT状态。我在多个UNIX平台(sun/hp/aix等)上都试过,这种CLOSE_WAIT状态不会自己关闭。所以每次都很痛苦,需要重启网卡。要么就重启系统。

【这个问题的引起可以通过kill服务和客户来快速解决,你如上的描述是不确切的,“此时再结束AAA,也无济于事”,你在结束后便迫不及待的用netstat -a|grep 6666看了状态,此时一般正在处于四分节终止的某一过程中,因为这个过程需要一段时间,因此你认为无济于事。】

请各位不吝赐教:
1、为什么fork一个进程便会产生一个CLOSE_WAIT状态?

【不是fork就会成生close_wait,而是应用程序的问题,具体参看论坛重的例子代码】

2、并且这种状态必须随着子进程的终止才能结束?
【哼,你不是说“此时再结束AAA,也无济于事”,现在却说种状态必须随着子进程的终止才能结束】

3、有没有方法避免或者解决这种CLOSE_WAIT的方法?
【有办法,问题出在应用代码】

我曾经尝试向6666端口发送RST标志位=1或者FIN=1的TCP包,也不能reset这个连接。
【很简单,因为两个断点的一段仍然存在】

论坛徽章:
0
11 [报告]
发表于 2003-07-09 13:36 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

最干脆的,把 SO_LINGER 设置上, 连 TIME_WAIT 都没有了.

论坛徽章:
0
10 [报告]
发表于 2003-07-09 11:04 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

jobman,我可是万万没有忘记closeaccept()的
究竟是怎么了?我再看看  多谢各位

论坛徽章:
0
9 [报告]
发表于 2003-07-09 03:44 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

忘了一句, 同时在子进程中关闭父进程的socket, 太绕口了,看

mainsock = socket(..);
.....
subsock=accept( mainsock....)

i=fock( .....)
if( i >; 0 )
{
close subsock;
}
else if( i == 0 )
{
close mainsock;
}
else
{
error;
}r

论坛徽章:
0
8 [报告]
发表于 2003-07-09 03:18 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

mushuang 说的对, 必须在 accept之后, 父进程关闭返回的
socket, 重用不解决根本问题.

论坛徽章:
0
7 [报告]
发表于 2003-07-08 19:09 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

键盘的TCP讨论(精华中)
里面有对CLOSE——WAIT说明
你想知道的话看看
或是UNIX网络编程中对CLOSE——WAIT状态的说明

论坛徽章:
0
6 [报告]
发表于 2003-07-08 19:07 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

多谢楼上各位!!!

mushuang,我不太理解您说的

还有楼上几位兄台,我看了精华区的文章,如果重用端口,那之前出现的CLOSE_WAIT不是依然存在吗?并且我想知道这个CLOSE_WAIT产生的原因。请教各位了。

gadfly,描述符我已关闭了。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
5 [报告]
发表于 2003-07-08 17:46 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

在socket之后
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, ...)
设置可重用这个端口


另外你exec方式执行AAA,AAA复制了父进程的描述符表,最好将所有不用的描述符关闭,像做daemon的方式那样,将所有的描述符关闭一遍。

论坛徽章:
0
4 [报告]
发表于 2003-07-08 17:43 |只看该作者

★请教:fork进程遇到端口状态不释放的问题★

看精华中的SETSOCKOPT

选项是REUSEADDR或是REUSEOPORT
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP