Linux网络编程怎么使用多进程实现服务器并发访问Word格式.docx
《Linux网络编程怎么使用多进程实现服务器并发访问Word格式.docx》由会员分享,可在线阅读,更多相关《Linux网络编程怎么使用多进程实现服务器并发访问Word格式.docx(3页珍藏版)》请在冰豆网上搜索。
socklen_tclilen;
structsockaddr_inservaddr;
structsockaddr_incliaddr;
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1){ fprintf(stderr,&
quot;
Socketerror:
%s\n\a&
strerror(errno));
exit
(1);
} /*服务器端填充sockaddr结构*/ bzero(&
amp;
servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(SERV_PORT);
/*捆绑listenfd描述符*/ if(bind(listenfd,(structsockaddr*)(&
servaddr),sizeof(structsockaddr))==-1){ fprintf(stderr,&
Binderror:
} /*监听listenfd描述符*/ if(listen(listenfd,5)==-1){ fprintf(stderr,&
Listenerror:
} for(;
;
){ clilen=sizeof(cliaddr);
/*服务器阻塞,直到客户程序建立连接*/ if((connfd=accept(listenfd,(structsockaddr*)(&
cliaddr),&
clilen))==-1){ fprintf(stderr,&
Accepterror:
} //有客户端建立了连接后 if((childpid=fork())==0){/*子进程*/ close(listenfd);
/*关闭监听套接字*/ str_echo(connfd);
/*处理该客户端的请求*/ exit(0);
} close(connfd);
/*父进程关闭连接套接字,继续等待其他连接的到来*/ } } voidstr_echo(intsockfd){ ssize_tn;
charbuf[MAXLINE];
again:
while((n=read(sockfd,buf,MAXLINE))&
gt;
0) write(sockfd,buf,n);
if(n&
lt;
0&
&
errno==EINTR)//被中断,重入 gotoagain;
elseif(n&
0){//出错 fprintf(stderr,&
readerror:
} } 客户端过程:
创建连接套接字,主动向服务器发起连接请求,建立连接后,等待标准输入,输入完成后,将输入的内容发送给服务器,接着接收服务器发送过来的内容,并将接收到的内容输出到标准输出。
代码如下:
#include #include #include #include #include #include #include #include #include #defineSERV_PORT1113 #defineMAXLINE1024 voidstr_cli(FILE*fp,intsockfd);
int main(intargc,char**argv) { intsockfd;
if(argc!
=2){ fprintf(stderr,&
usage:
tcpcli\n\a&
);
exit(0);
} if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){ fprintf(stderr,&
} /*客户程序填充服务端的资料*/ bzero(&
servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(SERV_PORT);
if(inet_pton(AF_INET,argv[1],&
servaddr.sin_addr)&
=0){ fprintf(stderr,&
inet_ptonError:
%s\a\n&
} /*客户程序发起连接请求*/ if(connect(sockfd,(structsockaddr*)(&
connectError:
} str_cli(stdin,sockfd);
/*doitall*/ exit(0);
} void str_cli(FILE*fp,intsockfd) { intnbytes=0;
charsendline[MAXLINE],recvline[MAXLINE];
while(fgets(sendline,MAXLINE,fp)!
=NULL){//从标准输入中读取一行 write(sockfd,sendline,strlen(sendline));
//将该行发送给服务器 if((nbytes=read(sockfd,recvline,MAXLINE))==0){//从sockfd读取从服务器发来的数据 fprintf(stderr,&
str_cli:
serverterminatedprematurely\n&
} recvline[nbytes]=&
#39;
\0&
;
fputs(recvline,stdout);
} } 运行结果:
1.首先启动服务器端程序。
viidiot@ubuntu$./dissrv&
(在后台运行) 2.启动一个客户端 viidiot@ubuntu$./discli127.0.0.1 hello,world!
(客户端输入的内容) hello,world!
(服务器端返回的内容) 3.输入命令netstat-at查看tcp的连接情况,可以发现服务器端与客户端已经建立起了一个连接,而服务器的主进程则仍然在1113端口监听,等待连接其他连接的到来。
viidiot@ubuntu$netstat&
ndash;
at tcp00*:
1113*:
*LISTEN tcp00localhost.localdom:
1113localhost.localdo:
57430ESTABLISHED tcp00localhost.localdo:
57430localhost.localdom:
1113ESTABLISHED 客户端输入EOF结束通信。
但是当我们开启多个客户端连接到服务器进行通信,完了之后通过按EOF结束通信后,可以从后台发现一个有趣的事情,即出现了大量的僵尸进程。
如下所示:
viidiot@ubuntu$ps-a PIDTTYTIMECMD 19403pts/100:
00:
00dissrv 19405pts/100:
00dissrv 19423pts/100:
00dissrv 19434pts/100:
00dissrv 19441pts/100:
00dissrv 造成大量僵尸进程的原因是,服务器子进程终止时,会发送一个SIGCHLD信号给父进程。
但我们的代码中,并没有捕获该信号,而这个信号的默认动作是忽略,因此,为了避免僵尸进程的产生,我们需要捕获SIGCHLD来清楚僵尸进程。
都清楚了么~如果觉得本文不错的话,就给小编我点个赞吧,就在文章下方哦!
!