多进程并发服务器
多线程并发服务器
I/O多路转接服务器
epoll的工作模式
1 多进程并发服务器
在多进程并发服务器中,若有用户请求到达,服务器将会调用fork()函数,创建一个子进程,之后父进程将继续调用accept(),而子进程则去处理用户请求。
【案例1】构建多进程并发服务器。
- 服务器端:接收多个客户端的数据,并将接收到的数据转为大写,写回客户端;
- 客户端:向服务器发送数据,并将服务器返回的数据打印到终端。
forkserver.c
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#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 %d\n",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 iWrite(tempConnFd, tempBuf, tempDataLen);}//of whileClose(tempConnFd);return 0;} else if (tempPid > 0) {Close(tempConnFd);} else {perr_exit("fork");}//of if}//of whileClose(tempListenFd);return 0;
}//of mainforkclient.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#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 whileClose(tempSockFd);return 0;
} //of main