多进程并发服务器
多线程并发服务器
I/O多路转接服务器
epoll的工作模式
在多进程并发服务器中,若有用户请求到达,服务器将会调用fork()函数,创建一个子进程,之后父进程将继续调用accept(),而子进程则去处理用户请求。
【案例1】构建多进程并发服务器。
- 服务器端:接收多个客户端的数据,并将接收到的数据转为大写,写回客户端;
- 客户端:向服务器发送数据,并将服务器返回的数据打印到终端。
forkserver.c #include #include#include #include #include "wrap.h" #define MAXLINE 80 //缓冲数组大小 #define SERV_PORT 8000 //端口号 //子进程回收函数 void doSigChild(int paraNum) { while (waitpid(0, NULL, WNOHANG) > 0); } //of doSigChild int main() { struct sockaddr_in tempServAddr, tempCliAddr; socklen_t tempCliAddrLen; int tempListenFd, tempConnFd; char tempBuf[MAXLINE]; char tempStr[INET_ADDRSTRLEN]; int i, tempDataLen; pid_t tempPid; struct sigaction tempNewAct; tempNewAct.sa_handler = doSigChild; sigaction(SIGCHLD, &tempNewAct, NULL); //信号捕获与处理(回收子进程) tempListenFd = Socket(AF_INET, SOCK_STREAM, 0); //设置服务器端口地址 bzero(&tempServAddr, sizeof(tempServAddr)); tempServAddr.sin_family = AF_INET; tempServAddr.sin_addr.s_addr = htonl(INADDR_ANY); tempServAddr.sin_port = htons(SERV_PORT); //使服务器与端口绑定 Bind(tempListenFd, (struct sockaddr *)&tempServAddr, sizeof(tempServAddr)); Listen(tempListenFd, 20); printf("Accepting connections ...n"); while (1) { tempCliAddrLen = sizeof(tempCliAddr); tempConnFd = Accept(tempListenFd, (struct sockaddr *)&tempCliAddr, &tempCliAddrLen); tempPid = fork(); //创建子进程 if (tempPid == 0) { //子进程处理客户端请求 Close(tempListenFd); while (1) { tempDataLen = Read(tempConnFd, tempBuf, MAXLINE); if (tempDataLen == 0) { printf("the other side has been closed.n"); break; }//of if //打印客户端端口信息 printf("received from %s at PORT %dn", inet_ntop(AF_INET, &tempCliAddr.sin_addr, tempStr, sizeof(tempStr)), ntohs(tempCliAddr.sin_port)); for (i = 0; i < tempDataLen; i++) { tempBuf[i] = toupper(tempBuf[i]); } //of for i Write(tempConnFd, tempBuf, tempDataLen); }//of while Close(tempConnFd); return 0; } else if (tempPid > 0) { Close(tempConnFd); } else { perr_exit("fork"); }//of if }//of while Close(tempListenFd); return 0; }//of main forkclient.c #include #include #include #include #include "wrap.h" #define MAXLINE 80 //缓冲数组大小 #define SERV_PORT 8000 //端口号 int main() { struct sockaddr_in tempServAddr; char tempBuf[MAXLINE]; int tempSockFd, tempDataLen; tempSockFd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&tempServAddr, sizeof(tempServAddr)); tempServAddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &tempServAddr.sin_addr); tempServAddr.sin_port = htons(SERV_PORT); Connect(tempSockFd, (struct sockaddr *)&tempServAddr, sizeof(tempServAddr)); while (fgets(tempBuf, MAXLINE, stdin) != NULL) { Write(tempSockFd, tempBuf, strlen(tempBuf)); tempDataLen = Read(tempSockFd, tempBuf, MAXLINE); if (tempDataLen == 0) { printf("the other side has been closed.n"); } else { Write(STDOUT_FILENO, tempBuf, tempDataLen); }//of if }//of while Close(tempSockFd); return 0; } //of main



