Artical–4–并发服务器
并发服务器用到了 fork() 和 信号量。测试时可以用之前的客户端代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define BUF_SIZE 30
void error_handling(char * message);
void read_childproc(int sig);int main(int argc,char * argv[])
{int serv_sock;int clnt_sock;char buf[BUF_SIZE];struct sockaddr_in serv_adr;struct sockaddr_in clnt_adr;pid_t pid;struct sigaction act;socklen_t adr_sz;int str_len,state;if(argc != 2){printf("usage : %s <port>\n",argv[0]);exit(1);}act.sa_handler=read_childproc;sigemptyset(&act.sa_mask);act.sa_flags=0;state=sigaction(SIGCHLD,&act,0);serv_sock=socket(PF_INET,SOCK_STREAM,0);memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);serv_adr.sin_port=htons(atoi(argv[1]));if(bind(serv_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr))==-1)error_handling("bind() error");if(listen(serv_sock,5)==-1)error_handling("listen() error");while(1){adr_sz=sizeof(clnt_adr);clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_adr,&adr_sz); if(clnt_sock==-1){printf("clnt_sock is -1\n");continue;}elseputs("new client connected...");pid=fork();if(pid==-1){close(clnt_sock);continue;}if(pid==0){close(serv_sock);while((str_len=read(clnt_sock,buf,BUF_SIZE))!=0)write(clnt_sock,buf,str_len);close(clnt_sock);puts("client disconnected...");return 0;}elseclose(clnt_sock);}close(serv_sock);return 0;
}void read_childproc(int sig){pid_t pid;int status;pid=waitpid(-1,&status,WNOHANG);printf("removed proc id: %d\n",pid);
}
void error_handling(char *message)
{fputs(message,stderr);fputc('\n',stderr);exit(1);}