C多进程实现聊天服务
一、概述
案例:使用多进程实现聊天服务。要求:可以有多个客户端连接,且客户端发送什么数据服务端就回复什么数据
实现步骤:
1.创建监听文件描述符socket
2.绑定端口bind
3.监听端口listen
4.当接受到一个连接时开启一个子进程来实现,来实现和客户端的通讯(fork)
5.具体客户端通讯的方法read\write
二、代码示例
//多进程版网络服务器(优化版) #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/wait.h> #include <signal.h> #include <ctype.h> #include "wrap.h" //信号处理函数 void waitchild(int signo){ pid_t wpid; while(1){ wpid = waitpid(-1,NULL,WNOHANG); if(wpid>0){ printf("child exit,wpid=[%d]\n",wpid); }else if(wpid==0||wpid==-1){ break; } } int main(){ //创建Socket int lfd = Socket(AF_INET,SOCK_STREAM,0); //设置端口复用 int opt; setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(int)); //绑定 struct sockaddr_in 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); //阻塞信号 sigset_t mask; sigemptyset(&mask); sigaddset(&mask,SIGCHLD); sigprocmask(SIG_BLOCK,&mask,NULL); int cfd; socklen_t len; char sIP[16]; pid_t pid; struct sockaddr_in client; while(1){ //等待客户端连接 memset(sIP,0x00,sizeof(sIP)); len = sizeof(client); bzero(&client,sizeof(client)); cfd = Accept(lfd,(struct sockaddr *)&client,&len); //创建子进程 pid = fork(); if(pid<0){//创建进程失败 perror("fork error"); close(lfd); return -1; }else if(pid>0){//如果是父进程 //关闭通讯描述符 close(cfd); //注册SIGCHLD信号处理函数 struct sigaction act; act.sa_handler = waitchild; act.sa_flags = 0; sigemptyset(&act.sa_mask); //解除对SIGCHLD信号的阻塞 sigprocmask(SIG_UNBLOCK,&mask,NULL); }else if(pid==0){//如果是子进程 //关闭监听文件描述符 close(lfd); int i =0; int n=0; char buf[1024]; while(1){ memset(buf,0x00,sizeof(buf)); n = Read(cfd,buf,sizeof(buf)); if(n<=0){ printf("read error or client closed,n==[%d]\n",n); break; } printf("read over,n==[%d],buf=[%s]\n",n,buf); for(i=0;i<n;i++){ buf[i] = toupper(buf[i]); } write(cfd,buf,n); } close(cfd); exit(0); } } //关闭监听文件描述符 close(lfd); return 0; }