第一种方案: 使用多进程, 可以让父进程接受新连接, 让子进程处理与客户端通信
思路: 让父进程accept接受新连接, 然后fork子进程, 让子进程处理通信, 子进程处理完成后退出, 父进程使用SIGCHLD信号回收子进程
第二种方案: 使用多线程, 让主线程接受新连接, 让子线程处理与客户端通信; 使用多线程要将线程设置为分离属性, 让线程在退出之后自己回收资源
如何不使用多进程或者多线程完成多个客户端的连接请求
将accept和read函数设置为非阻塞, 调用fcntl函数可以将文件描述符设置为非阻塞, 让后再while循环中忙轮询,但无法判断数据是哪个连接的,假如有多个客户端连接请求,cfd只会保留最后一个文件描述符的值
多进程并发服务器//多进程版本网络服务器 #include#include #include #include #include #include #include #include int main() { //创建socket int lfd=socket(AF_INET,SOCK_STREAM,0); //绑定 struct sockaddr_in serv; bzero(&serv,sizeof(serv)); serv.sin_family=AF_INET; serv.sin_port=htons(8888); serv.sin_addr.s_addr=htonl(INADDR_ANY); bind(lfd,(struct sockaddr*)&serv,sizeof(serv)); //设置监听 listen(lfd,128); int cfd; while(1) { //接受新连接 cfd=accept(lfd,NULL,NULL); pid_t pid=fork(); if(pid<0) { perror("fork error"); exit(-1); } else if(pid>0) { //关闭通信文件描述符cfd close(cfd); } else if(pid==0) { //关闭监听文件描述符 close(lfd); int n; char buf[1024]; while(1) { //读数据 n=read(cfd,buf,sizeof(buf)); if(n<=0) { printf("read error or client close,n==[%d]n",n); break; } int i=0; //将小写转为大写 for(i=0;i 多线程并发服务器 子线程不能关闭监听文件描述符,因为子线程和主线程共享文件描述符而不是复制
主线程不能关闭cfd,主线程和子线程共享一个cfd,而不是复制的
#include#include #include #include #include #include #include #include #include void* thread_work(void* arg) { int cfd=*(int*)arg; int i; int n; char buf[1024]; while(1) { //read数据 memset(buf,0x00,sizeof(buf)); n=read(cfd,buf,sizeof(buf)); if(n<=0) { printf("read error or client close,n==[%d]n",n); break; } printf("n==[%d],buf==[%s]n",n,buf); for(i=0;i



