程式說明: 多進程並發,在接收到請求時,fork個進程,對父進程則關閉串連Socket,而子進程則關閉監聽socket,每一個新的accept請求都由子進程來執行,而由父進程繼續listen.
/**************************************************************************** author: denny wqf363@hotmail.com 2006 * desc: 多進程並發* 座友銘:凡是程式當前不需要的,都是垃圾,80%的時間做20%的事情。(程式的效率)* ****************************************************************************/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <pthread.h>#include <malloc.h>#include <stdlib.h> #define BACKLOG 5#define MAXDATASIZE 1000#define PORT 1234 void process_cli(int,sockaddr_in); int main(int argc,char *argv[]) //需要一個參數 連接埠號碼{ int listenfd, //監聽通訊端sock connectfd; //accept 收到的 新通訊端 struct sockaddr_in servAddr, //伺服器位址 cliAddr; //用戶端地址 socklen_t adrlen; //sockaddr地址長度 int servPort; //伺服器監聽連接埠號碼 pid_t pid; //獲得伺服器監聽的連接埠號碼 if(argc!=2) { printf("Usage:%s portnumber/a/n",argv[0]); return 1; } if((servPort=atoi(argv[1]))<0) { printf("Usage:%s portnumber/a/n",argv[0]); return 1; } /* 伺服器端開始建立socket描述符 */ if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket error:%s/n/a",strerror(errno)); return 1; } /*設定通訊端地址結構體servAddr中的參數,綁定伺服器連接埠號碼*/ servAddr.sin_family=AF_INET; servAddr.sin_addr.s_addr=htonl(INADDR_ANY); servAddr.sin_port=htons(servPort); if(bind(listenfd,(struct sockaddr *)&servAddr,sizeof(servAddr))<0) { printf("Bind error:%s/n/a",strerror(errno)); exit(2); } /* 監聽sockfd描述符 */ if(listen(listenfd,BACKLOG)==-1) { printf("Listen error:%s/n/a",strerror(errno)); exit(3); } while(1) { printf("%s:waiting for data on port TCP %u/n",argv[0],servPort); adrlen=sizeof(struct sockaddr_in); connectfd=accept(listenfd,(struct sockaddr *)&cliAddr,&adrlen); if(connectfd<0) { perror("accetp() error/n"); exit(4); } //採用多進程 if((pid=fork()) >0) { close(connectfd); continue; } else if(pid==0) { close(listenfd); process_cli(connectfd,cliAddr); exit(0); } else { printf("fork() error./n"); exit(0); } } close(listenfd);} void process_cli(int connectfd, sockaddr_in client){ //.... close(connectfd);}