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;
}
浙公网安备 33010602011771号