5.20作业

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;
}
相关推荐
眠修13 分钟前
Kuberrnetes 服务发布
linux·运维·服务器
开-悟20 分钟前
嵌入式编程-使用AI查找BUG的启发
c语言·人工智能·嵌入式硬件·bug
chirrupy_hamal1 小时前
如何避免 SYN 攻击?
网络·tcp
即将头秃的程序媛3 小时前
centos 7.9安装tomcat,并实现开机自启
linux·运维·centos
fangeqin3 小时前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
爱奥尼欧5 小时前
【Linux 系统】基础IO——Linux中对文件的理解
linux·服务器·microsoft
超喜欢下雨天5 小时前
服务器安装 ros2时遇到底层库依赖冲突的问题
linux·运维·服务器·ros2
Natsume17105 小时前
嵌入式开发:GPIO、UART、SPI、I2C 驱动开发详解与实战案例
c语言·驱动开发·stm32·嵌入式硬件·mcu·架构·github
清沫6 小时前
键盘效率提升指南(VSCode+Vim+SurfingKeys)
前端·vim·visual studio code
tan77º6 小时前
【Linux网络编程】网络基础
linux·服务器·网络