多进程并发服务器
服务器server执行accept函数等待客户端A,B,C,D与之建立连接,假设客户端A与服务器建立连接时,服务器在就创建一个子进程,子进程负责与客户端A进行数据交互, (如果其他客户端再与服务器进行连接,而服务器忙着与A进行数据交互,则不会顾及其他客户端,这也是他的缺点),而父进程则继续监听其他客户端,当其他客户端进行连接时,服务器再创建一个新的子进程与之进行交互.
当父进程与与客户端连接完成后,会产生一个cfd和lfd , 当fork()产生一个子进程时,则会将这个cfd与lfd 继承,cfd可以用于与客户端进行数据交互,而lfd对于子进程来说并没有用处,所以子进程要将继承的lfd关闭.对于父进程来说父进程不需要与其他客户端进行数据交互,所以父进程需要关闭cfd.
子进程完成与客户端的数据交互后,子进程会退出变成僵尸进程,所以父进程要对子进程进行回收.可以用回调机制,利用信号进行处理:利用SIGCHLD注册信号捕捉函数,在捕捉函数内调用waitpid()回收子进程
使用多进程并发服务器时要考虑以下几点:
- 父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符)
- 系统内创建进程个数(与内存大小相关)
- 进程创建过多是否降低整体服务性能(进程调度)
多线程高并发服务器实现将字符串转化大写
客户端往服务器端发送字符串,服务器把字符串转换成大写之后再发送回给客户端。
大致流程:
server.cpp
#include <iostream>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <ctype.h>
#include <strings.h>
#include <assert.h>
using namespace std;
#define MAXLINE 4096
#define SERV_PORT 8000
//信号捕捉函数,信号:SIGCHLD:当子进程状态发生变化(退出或暂停)时产生
void do_sigchild(int num){
while(waitpid(0,NULL,WNOHANG) > 0){
//回收子进程
}
}
int main(){
struct sockaddr_in servaddr,cliaddr;
socklen_t cliaddr_len = sizeof(cliaddr);
int listenfd,connfd;
char buf[MAXLINE]</