网络第4天

TCP并发服务器(多进程)

cpp 复制代码
#include <myhead.h>
#define IP "192.168.124.74"
#define PORT 6666


int fork_child(int newfd,struct sockaddr_in cin);

void re_fork(){
	while(waitpid(-1,NULL,WNOHANG)>0);
}

int main(int argc, const char *argv[])
{
	if(signal(17,re_fork)==SIG_ERR){
		ERR_MSG("signal");
		return -1;
	}

	//创建socket文件
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	printf("sfd create success\n");

	//绑定服务器的IP和端口号
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(PORT);
	sin.sin_addr.s_addr=inet_addr(IP);

	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){
		ERR_MSG("bind");
		return -1;
	}
	printf("bind IP&PORT success\n");

	//将文件转为被动监听模式
	if(listen(sfd,128)<0){
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success\n");

	struct sockaddr_in cin;
	socklen_t len=sizeof(cin);
	int newfd =0;
	int cpid=0;
	while(1){
		//用连接成功的客户端的信息生成accept文件

		newfd=accept(sfd,(struct sockaddr*)&cin,&len);
		if(newfd<0){
			ERR_MSG("accept");
			return -1;
		}	
		cpid=fork(); //父进程创建newfd,子进程负责通信
		if(cpid==0){
			fork_child(newfd,cin);
			exit(0);
		}else if(cpid<0){
			ERR_MSG("fork");
			return -1;
		}
		//把客户端的IP和端口提出来
		printf("newfd:%d %s:%d 连接成功\n",newfd\
				,inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));

		close(newfd);//后面每个的进程文件号都是4,因为被父进程关了
	}
	//关闭所有文件描述符
	close(sfd);

	return 0;
}

int fork_child(int newfd,struct sockaddr_in cin)
{
	char buf[128]="";
	ssize_t res=0;

	while(1){
		bzero(buf,sizeof(buf));
		//接收客户端数据
		res=recv(newfd,&buf,sizeof(buf),0);
		if(res<0){
			ERR_MSG("recv");
			break;
		}else if(res==0){
			printf("客户端下线\n");
			break;
		}
		printf("[%s:%d]:%s\n",\
				inet_ntoa(cin.sin_addr),\
				ntohs(cin.sin_port),buf);

		//向客户端发送数据
		//要发送的数据
		strcat(buf,"^-^");
		res=send(newfd,buf,sizeof(buf),0);
		if(res<0){
			ERR_MSG("send");
			return -1;
		}
		printf("send success\n");
	}
	return 0;
}

TCP并发服务器(多线程)

cpp 复制代码
#include <myhead.h>
#define IP "192.168.124.74"
#define PORT 6666

struct data{
	int newfd;
	struct sockaddr_in cin;
};

void* pthread_child(void* arg);

int main(int argc, const char *argv[])
{
	
	//创建socket文件
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	printf("sfd create success\n");

	//允许端口快速被复用---监测端口号是否真的有进程在占用,如果没有,则快速复用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("允许端口快速复用成功\n");

	//绑定服务器的IP和端口号
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(PORT);
	sin.sin_addr.s_addr=inet_addr(IP);
	
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){
		ERR_MSG("bind");
		return -1;
	}
	printf("bind IP&PORT success\n");

	//将文件转为被动监听模式
	if(listen(sfd,128)<0){
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success\n");

	struct sockaddr_in cin;
	socklen_t len=sizeof(cin);
	pthread_t tid;
	struct data info;
	
	while(1){
		//用连接成功的客户端的信息生成accept文件

		info.newfd=accept(sfd,(struct sockaddr*)&info.cin,&len);
		if(info.newfd<0){
			ERR_MSG("accept");
			return -1;
		}
		
		//把客户端的IP和端口提出来
		printf("newfd:%d %s:%d 连接成功\n",info.newfd\
				,inet_ntoa(info.cin.sin_addr),ntohs(info.cin.sin_port));

		//创建线程
		if(pthread_create(&tid,NULL,pthread_child,(void*)&info)!=0){
			printf("pthread_child create fail\n");
			return -1;
		}
		//分离线程:join会阻塞,使用detach直接分离回收
		if(pthread_detach(tid)!=0){
			printf("pthread_detach fail\n");
			return -1;
		}

	}
	//关闭所有文件描述符
	close(sfd);
	return 0;
}

void* pthread_child(void* arg) //void* arg=&info
{
    //必须转存,因为info每连接一个客户端就会改变
	int newfd=((struct data*)arg)->newfd;
	struct sockaddr_in cin=((struct data*)arg)->cin;

	ssize_t res=0;
	char buf[128]="";
	while(1){
		bzero(buf,sizeof(buf));
		//接收客户端数据
		res=recv(newfd,&buf,sizeof(buf),0);
		if(res<0){
			ERR_MSG("recv");
			break;
		}else if(res==0){
			printf("客户端下线\n");
			break;
		}
		printf("[%s:%d]:%s\n",\
				inet_ntoa(cin.sin_addr),\
				ntohs(cin.sin_port),buf);

		//向客户端发送数据
		//要发送的数据
		strcat(buf,"^-^");
		res=send(newfd,buf,sizeof(buf),0);
		if(res<0){
			ERR_MSG("send");
			break;
		}
		printf("send success\n");
	}
	close(newfd);
}
相关推荐
韩立学长34 分钟前
【开题答辩实录分享】以《基于Python的大学超市仓储信息管理系统的设计与实现》为例进行选题答辩实录分享
开发语言·python
树℡独1 小时前
ns-3仿真之应用层(五)
服务器·网络·tcp/ip·ns3
froginwe111 小时前
Scala 循环
开发语言
m0_706653231 小时前
C++编译期数组操作
开发语言·c++·算法
故事和你911 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
Bruk.Liu2 小时前
(LangChain实战2):LangChain消息(message)的使用
开发语言·langchain
qq_423233902 小时前
C++与Python混合编程实战
开发语言·c++·算法
m0_715575342 小时前
分布式任务调度系统
开发语言·c++·算法
zhang133830890752 小时前
CG-09H 超声波风速风向传感器 加热型 ABS材质 重量轻 没有机械部件
大数据·运维·网络·人工智能·自动化
csbysj20202 小时前
选择(Selectable)
开发语言