TCP多进程并发
objectivec#include <header.h> #define SER_PORT 8888 #define SER_IP "192.168.125.192" void handle(int signum) { if(signum==SIGCHLD) { while(waitpid(-1,NULL,WNOHANG)>0); } } int main(int argc, const char *argv[]) { //将子进程的SIGCHLD(17)信号 //当子进程退出时,会向其父进程发送该信号 if(signal(SIGCHLD,handle)==SIG_ERR) { perror("signal"); return -1; } //为进程创建一个端点 int sfd=socket(AF_INET,SOCK_STREAM,0); if(sfd==-1) { perror("socket"); return -1; } printf("socket success! sfd=%d\n",sfd); //端口号快速重用 int reuse=1; if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1) { perror("setsockopt error"); return -1; } //准备地址信息结构体 struct sockaddr_in sin; sin.sin_family=AF_INET; sin.sin_port=htons(SER_PORT); sin.sin_addr.s_addr=inet_addr(SER_IP); //绑定地址信息 if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1) { perror("bind"); return -1; } printf("bind success!\n"); //将套接字设置成被动监听状态 if(listen(sfd,128)==-1) { perror("listen"); return -1; } printf("listen success!\n"); //阻塞等待客户端的连接 //定义用于接收客户端信息的容器 struct sockaddr_in cin; socklen_t addrlen=sizeof(cin); int newfd=-1; while(1) { newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen); if(newfd==-1) { perror("accept"); return -1; } printf("[%s:%d]:发来连接请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port)); //创建子进程 pid_t pid=fork(); if(pid>0) { //关闭newfd close(newfd); } else if(pid==0) { //关闭sfd close(sfd); //与客户端进行相互通信 char rbuf[128]={0}; //读取消息内容的容器 while(1) { //清空容器 bzero(rbuf,sizeof(rbuf)); //从套接字中读取数据 //int res=read(newfd,rbuf,sizeof(rbuf)); int res=recv(newfd,rbuf,sizeof(rbuf),0); if(res==0) { printf("客户端已经下线\n"); break; } //将读取的消息展示出来 printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf); //将收的的消息处理一下,回复给客户端 strcpy(rbuf,"^_^"); //write(newfd,rbuf,strlen(rbuf)); send(newfd,rbuf,strlen(rbuf),0); printf("发送成功\n"); } //关闭套接字 close(newfd); //退出子进程 exit(EXIT_SUCCESS); } else { perror("fork"); return -1; } } close(sfd); return 0; }
TCP多线程并发
objectivec#include <header.h> #define SER_PORT 8888 #define SER_IP "192.168.125.192" //定义一个像线程体函数传参的结构体 struct Info { int newfd; struct sockaddr_in cin; }; //定义线程函数 void *deal_cli_msg(void *arg) { //解析传过来的数据 int newfd=((struct Info*)arg)->newfd; struct sockaddr_in cin=((struct Info*)arg)->cin; //与客户端进行通信 char buf[128]={0}; while(1) { //清空容器 bzero(buf,sizeof(buf)); //从套接字中读取数据 int res=recv(newfd,buf,sizeof(buf),0); if(res==0) { printf("客户端已下线\n"); break; } //将读取的消息展示出来 printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf); //将收到的消息处理一下,回复给客户端 strcat(buf,"^_^"); //将消息发送给客户端 send(newfd,buf,strlen(buf),0); printf("发送成功\n"); } //关闭套接字 close(newfd); //退出线程 pthread_exit(NULL); } int main(int argc, const char *argv[]) { //为通信创建一个端点 int sfd=socket(AF_INET,SOCK_STREAM,0); if(sfd==-1) { perror("socket"); return -1; } printf("socket success! sfd=%d\n",sfd); //准备服务器地址信息结构体 struct sockaddr_in sin; sin.sin_family=AF_INET; sin.sin_port=htons(SER_PORT); sin.sin_addr.s_addr=inet_addr(SER_IP); //绑定服务器地址信息 if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1) { perror("bind"); return -1; } printf("bind success!\n"); //将套接字设置成被动监听状态 if(listen(sfd,128)==-1) { perror("listen"); return -1; } printf("listen success!\n"); //阻塞等待客户端连接 //定义接收客户端信息的结构体容器 struct sockaddr_in cin; socklen_t addrlen=sizeof(cin); while(1) { //accept函数会与选一个当前未分配的最小的文件描述符 //即使在阻塞过程中,有更小的文件描述符产生,本次操作的文件描述符也不会更改 int newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen); if(newfd==-1) { perror("accept"); return -1; } printf("[%s:%d]:发来连接请求,newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd); //定义要传递数据的结构体变量 struct Info buf={newfd,cin}; //创建分支线程,用于通信 pthread_t tid=-1; if(pthread_create(&tid,0,deal_cli_msg,&buf)==-1) { printf("pthread_create\n"); return -1; } pthread_detach(tid); } close(sfd); return 0; }
5.20作业
sjdghjh2024-05-21 16:30
相关推荐
懒大王就是我30 分钟前
C语言网络编程 -- TCP/iP协议半盏茶香33 分钟前
【C语言】分支和循环详解(下)猜数字游戏小堇不是码农39 分钟前
在VScode中配置C_C++环境小肥象不是小飞象1 小时前
(六千字心得笔记)零基础C语言入门第八课——函数(上)pk_xz1234562 小时前
Shell 脚本中变量和字符串的入门介绍小珑也要变强2 小时前
Linux之sed命令详解Lary_Rock4 小时前
RK3576 LINUX RKNN SDK 测试云飞云共享云桌面6 小时前
8位机械工程师如何共享一台图形工作站算力?励志成为嵌入式工程师6 小时前
c语言简单编程练习9Peter_chq6 小时前
【操作系统】基于环形队列的生产消费模型