国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 互联网 > Socket编程实践(8) --TCP服务器常见问题(3)

Socket编程实践(8) --TCP服务器常见问题(3)

来源:程序员人生   发布时间:2014-12-19 08:38:08 阅读次数:2318次

服务端多进程避免僵尸进程的方法

1)通过疏忽SIGCHLD信号,解决僵尸进程

    在server端代码中添加

signal(SIGCHLD, SIG_IGN);

2)通过wait/waitpid方法,解决僵尸进程

  signal(SIGCHLD,onSignalCatch);      void onSignalCatch(int signalNumber)   {    wait(NULL);   }

Server端部份代码:

//return a socket that have start listened. int mkATCPServer(int serverPort, int backlog = SOMAXCONN) { int sockfd = socket(AF_INET,SOCK_STREAM,0); if (sockfd == ⑴) { err_exit("socket error"); } //add address reused int on = 1; if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) == ⑴) { err_exit("setsockopt SO_REUSEADDR error"); } //band a local address and port struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(serverPort); serverAddr.sin_addr.s_addr = INADDR_ANY; //band an any IP address if (bind(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr)) == ⑴) { err_exit("bind error"); } //start to listen. if (listen(sockfd,backlog) == ⑴) { err_exit("listen error"); } return sockfd; } void onSignalCatch(int signalNumber) { waitpid(⑴,NULL,WNOHANG); } int main() {   //安装SIGCHLD信号处理函数 signal(SIGCHLD,onSignalCatch); int serverSockfd = mkATCPServer(8002); struct sockaddr_in peerAddr; socklen_t peerLen = sizeof(peerAddr); while (true) { //接受链接 int peerSockfd = accept(serverSockfd, (struct sockaddr *)&peerAddr,&peerLen); if (peerSockfd == ⑴) { err_exit("accept error"); } ..... //其他部份代码与前面类似

多客户端同时关闭问题

问题描写以下:



客户端代码实现代码

//其他代码如前 //.... int main() { int serverSocket[10]; int socketCount = 10; for (int i = 0; i < socketCount; ++i) { serverSocket[i] = mkATCPClient(8002,"127.0.0.1"); } sleep(100); return 0; }

 在客户运行进程中按下Ctrl+C,则可以看到在server端启动10个子进程,并且所有的客户端全部1起断开的情况下,产生的僵尸进程数是惊人的(此时也证明了SIGCHLD信号是不可靠的)!

 

 

解决方法:

//server端部份代码以下: //其他如前.... void onSignalCatch(int signalNumber) {   int ret = 0;   //注意此处!!!! while ((ret = waitpid(⑴,NULL,WNOHANG) != ⑴)) ; } int main() { signal(SIGCHLD,onSignalCatch); int serverSockfd = mkATCPServer(8002);   ...

从下图可以看出,出了监听server进程,已没有僵尸进程了!



生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生