Linux编程基础 8.1:高并发服务器-1

Linux编程基础 8.1:高并发服务器-1,第1张

多进程并发服务器
多线程并发服务器
I/O多路转接服务器
epoll的工作模式

1 多进程并发服务器

在多进程并发服务器中,若有用户请求到达,服务器将会调用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 %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 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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/926779.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存