- 论坛徽章:
- 0
|
本帖最后由 cicy821@126.com 于 2011-06-29 19:21 编辑
写一个socket-server程序,此程序需要支持多连接,采用的是每接收到一个client的connection后fork出来一个子进程进行处理。
源码如下:
sigset(SIGPIPE, SIG_IGN); //忽略SIGPIPE信号,忽略SIGCHLD信号,父进程不关心子进程何时退出,有系统回收资源。
sigset(SIGCHLD, SIG_IGN);
int pids=waitpid(-1, 0, WNOHANG); /*wait any child process to exit */ //是否多余?
int iSock=TcpServerSocket(listenport);
if(iSock<0)
{
close(iSock);
iSock=-1;
sleep(1);
}
len = sizeof(sockaddr);
asock = accept(iSock, (struct sockaddr *)&sin, &len);
if(asock < 0)
{
continue;
}
if( (cpid=fork())==0 ) /* child process */
{
// 需要关闭listen状态的句柄
//close(iSock); //子进程是否需要关闭父进程的listen句柄?个人觉得应该不应该关闭
AGTCLIENT agtclnt;
agtclnt.start(asock); //子进程执行函数,函数为死循环除非异常否则永远不会退出
exit(0);
}
else if(cpid > 0) /*parent process*/
{
/*close(asock);
asock = -1;*/ //父进程是否需要关闭子进程的accept句柄?个人觉得应该不应该关闭
sleep(10);
//if((cpid=waitpid(cpid,&status,WNOHANG))<0) /*wait for child process exit*/ //此处还需要父进程waitpid吗?前面已经做了信号忽略。主要问题是子进程为死循环独立运行,永远不会返回或者退出,除非出现异常,所以父进程永远等不到子进程的退出。 //olog.logwrite(LOG_TIME|MAJOR,mainlogname,"waitpid error\n");
}
}
请大虾指导一下,我是否还有其他地方没有注意,或者请大虾分享一下写的支持socket多连接的实现方案。
我重点关注了:
1、增加信号忽略避免僵尸进程
目前这个状态的程序在使用client测试时,如果出现异常就出现连接状态不释放的情况。
即此程序监听的端口查看状态为,多个 ESTABLISHED状态,而实际的连接确只有二个:
netstat -an |grep 9090
tcp 0 0 127.0.0.1.60731 127.0.0.1.9090 ESTABLISHED
tcp 0 0 16.157.88.223.9090 16.157.88.223.60924 ESTABLISHED
tcp 0 0 16.157.88.223.9090 16.157.88.223.65240 ESTABLISHED
tcp 0 0 127.0.0.1.52236 127.0.0.1.9090 ESTABLISHED
tcp 0 0 16.157.88.223.9090 16.157.88.223.65500 ESTABLISHED
tcp 0 0 16.157.88.223.65500 16.157.88.223.9090 ESTABLISHED
tcp 0 0 127.0.0.1.9090 127.0.0.1.54030 ESTABLISHED
tcp 0 0 127.0.0.1.54030 127.0.0.1.9090 ESTABLISHED
tcp 0 0 16.157.88.223.65240 16.157.88.223.9090 ESTABLISHED
tcp 0 0 127.0.0.1.9090 127.0.0.1.60731 ESTABLISHED
tcp 0 0 16.157.88.223.60924 16.157.88.223.9090 ESTABLISHED
tcp 0 0 16.157.88.223.61817 16.157.88.223.9090 ESTABLISHED
tcp 0 0 127.0.0.1.9090 127.0.0.1.52236 ESTABLISHED
tcp 0 0 127.0.0.1.63711 127.0.0.1.9090 ESTABLISHED
tcp 0 0 16.157.88.223.9090 16.157.88.223.61150 ESTABLISHED
tcp 0 0 16.157.88.223.61150 16.157.88.223.9090 ESTABLISHED
tcp 0 0 16.157.88.223.9090 16.157.88.223.61817 ESTABLISHED
tcp 0 0 16.157.88.223.56796 16.157.88.223.9090 ESTABLISHED
tcp 0 0 127.0.0.1.9090 127.0.0.1.63711 ESTABLISHED
tcp 0 0 *.9090 *.* LISTEN
tcp 0 0 16.157.88.223.9090 16.157.88.223.56796 ESTABLISHED
如上的9090端口可以监听是程序设置了端口复用。实际的连接只有二个,其他连接都是非正常连接。超过了keepalive_interval=15秒系统的 ESTABLISHED
状态也是不释放。
使用lsof工具看9090端口连接,没有看到任何应用程序连接此端口,此端口无任何记录。
为什么ESTABLISHED状态不释放?查看了系统设计的keepalive_interval为15000毫秒=15秒。
请大虾支招,深表感谢。 |
|