tcp(二)---多进程TCP

来源:互联网 发布:便携音箱推荐 知乎 编辑:程序博客网 时间:2024/06/07 15:47


         用多进程方式实现一个TCP并发服务器,每当一个新的客户端连接时fork一个子进程去和它通信。(各种主流的web服务器都不是纯粹的多进程方式运行,比如apache在每个进程中都用多路复用方式,直到连接数多到超过select可监听的最大描述符数时也会利用新的进程去处理。)

//server.c

 #include<stdio.h>#include<stdlib.h>#include <sys/types.h>         #include <sys/socket.h>#include<arpa/inet.h>#include<netinet/in.h>#include <unistd.h>#include<sys/wait.h>int startup(int _port,const char* _ip){int sock=socket(AF_INET,SOCK_STREAM,0);if(sock<0){perror("socket");exit(1);}int opt=1;setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));struct sockaddr_in local;local.sin_family=AF_INET;local.sin_port=htons(_port);local.sin_addr.s_addr=inet_addr(_ip);socklen_t len=sizeof(local);if(bind(sock,(struct sockaddr*)&local,len)<0){perror("bind");exit(2);}if(listen(sock,5)<0){perror("listen");exit(3);}return sock;}int main(int argc,char* argv[]){if(argc!=3){printf("usage: %s [local_ip] [local_port]\n",argv[0]);return 3;}int listen_sock=startup(atoi(argv[2]),argv[1]);struct sockaddr_in remote;socklen_t len=sizeof(remote);while(1){int sock=accept(listen_sock,(struct sockaddr*)&remote,&len);if(sock<0){perror("accept"); continue;}printf("get a client,ip:%s,port:%d\n",inet_ntoa(remote.sin_addr),ntohs(remote.sin_port));pid_t id = fork();if(id<0){perror("fork");close(sock);}else if(id==0){//child            close(listen_sock);char buf[1024];while(1){ssize_t _s=read(sock,buf,sizeof(buf)-1);if(_s>0){buf[_s]=0;printf("client#:%s\n",buf);}else{printf("client is quit!\n");break;}}close(sock);}else{//fatherclose(sock);while(waitpid(-1,NULL,WNOHANG));}}return 0;}



client.c

#include<stdio.h>#include<stdlib.h>#include <sys/types.h>         #include <sys/socket.h>#include<arpa/inet.h>#include<netinet/in.h>#include <unistd.h>static void usage(const char* proc){printf("usage: %s [ip] [port]\n",proc);}int main(int argc,char* argv[]){if(argc!=3){    usage(argv[0]);return 3;}int sock=socket(AF_INET,SOCK_STREAM,0);if(sock<0){perror("socket");return 1;}struct sockaddr_in server;server.sin_family=AF_INET;server.sin_port=htons(atoi(argv[2]));server.sin_addr.s_addr=inet_addr(argv[1]);if(connect(sock,(struct sockaddr*)&server,sizeof(server))<0){perror("connect");return 2;}char buf[1024];while(1){printf("send#");fflush(stdout);ssize_t s=read(0,buf,sizeof(buf)-1);buf[s-1]=0;write(sock,buf,s);}    close(sock);return 0;}

运行结果:

client1


client2


server服务



        需要注意的一点是fork子进程以后需要对子进程关闭监听套接口,对父进程关闭连接套接口


0 0