本文共 3094 字,大约阅读时间需要 10 分钟。
首先,为什么要用多进程处理,多进程的好处是可靠性高,而且在处理大量数据的时候,多进程的速度会比多线程快,所有多进程还是要掌握的。
在一些实际项目中,进程和线程要根据实际场景用。
但是多进程是不能共享进程空间的,所以有很多变量都不能共享。除了fork()之前的变量是可以共享的。
下面的代码基本逻辑就是,用父进程来 accept,检测有没有新的客户端要连入,用子进程来接受客户端发来的信息
下面给出服务端的代码:(有详细注释)
#include"myhead.h"char rbuf[50];char wbuf[50];char ipbuf[50];int main(){ signal(SIGCHLD,SIG_IGN);//把子进程的僵尸进程给init进程处理 struct sockaddr_in saddr; struct sockaddr_in caddr; int size,len,opt = 1; int sockfd,newfd; pid_t pid; int err; size = sizeof(struct sockaddr_in); len = sizeof(struct sockaddr); //初始化本地ip,地址信息 bzero(&saddr,size); saddr.sin_family = AF_INET; saddr.sin_port = htons(8888); saddr.sin_addr.s_addr = htonl(INADDR_ANY); //创建一个监听套接字 sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd<0) { perror("failed socket"); return -1; } //设置端口复用 err = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt); if(err<0) { perror("setsockopt failed"); return -1; } //绑定套接字和IP,地址信息 err = bind(sockfd,(struct sockaddr*)&saddr,len); if(err<0) { perror("failed bind"); return -1; } //开始监听 listen(sockfd,10); //循环接收 客户端的连入 while(1) { //监测有没有新的客户端连入,有的话,返回新的套接字 newfd = accept(sockfd,(struct sockaddr*)&caddr,&len); if(newfd<0) { perror("accept failed"); continue; } //有新的客户端连入,则打印他的IP和端口 inet_ntop(AF_INET,(void*)&caddr.sin_addr.s_addr, ipbuf,50); printf("the client:%s is in\n", ipbuf); //创建一个子进程来接受新客户端的信息 pid = fork(); if(pid<0) //fork失败 { perror("failed fork()"); return -1; } else if(pid == 0) //子进程 { close(sockfd);//关闭从父进程进程来的监听套接字 //因为在子进程用不到 /*关闭不需要的套接字可节省系统资源, 同时可避免父子进程共享这些套接字 可能带来的不可预计的后果 */ //这个子进程循环接收客户端信息 while(1) { err = recv(newfd,rbuf,50,0); if(err<0) { perror("failed recv"); } //若recv的返回=0,表示客户端已经断开 else if(err == 0) { bzero(ipbuf,50); inet_ntop(AF_INET,(void*)&caddr.sin_addr.s_addr, ipbuf,50); printf("the client:%s is out\n", ipbuf); exit(0); close(newfd); } //读取客户端的信息 else { inet_ntop(AF_INET,(void*)&caddr.sin_addr.s_addr, ipbuf,50); printf("ip:%s,port:%d\n",ipbuf,ntohs(caddr.sin_port)); printf("%s\n",rbuf); bzero(rbuf,50); } } } else if(pid>0) //父进程,用于继续监测有没有新的客户端连入 { close(newfd);//关闭新客户端返回的套接字,因为在 //父进程中用不到 continue; } }}
#include "myhead.h"char wbuf[50];int main(){ struct sockaddr_in saddr; struct sockaddr_in caddr; int size,len,opt = 1; int sockfd,newfd; pid_t pid; int err; size = sizeof(struct sockaddr_in); len = sizeof(struct sockaddr); bzero(&saddr,size); saddr.sin_family = AF_INET; saddr.sin_port = htons(8888); saddr.sin_addr.s_addr = inet_addr("192.168.106.128"); sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd<0) { perror("failed socket"); return -1; } err = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt); if(err<0) { perror("setsockopt failed"); return -1; } err = connect(sockfd,(struct sockaddr*)&saddr, sizeof(struct sockaddr)); if(err<0) { perror("failed connect"); return -1; } while(1) { scanf("%s",wbuf); write(sockfd,wbuf,50); bzero(wbuf,50); }}
转载地址:http://oqfh.baihongyu.com/