epoll的并发服务器(TCP服务器与客户端通信)

服务器:

复制代码
#include<myhead.h>
#define IP "192.168.250.100"
#define PORT 8888
/*
typedef union epoll_data {
	void        *ptr;
	int          fd;
	uint32_t     u32;
	uint64_t     u64;
} epoll_data_t;

struct epoll_event {
	uint32_t     events;      	
	epoll_data_t data;        
};
*/

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
	}
	printf("socket success\n");
	//允许端口快速被重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
	}
	printf("setsockopt 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");
	}
	printf("bind success\n");

	//设置套接字为被动监听状态
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
	}
	printf("listen success\n");

	//存储客户端地址信息
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin);

	//定义事件结构体
	struct epoll_event event;
	//定义存放就绪事件描述符的数组
	struct epoll_event events[10];

	//创建红黑树根节点
	int epfd = epoll_create(1);
	if(epfd<0)
	{
		ERR_MSG("epoll_create");
	}
	printf("成功创建红黑树根节点\n");

	//添加要检测的事件描述符
	event.events=EPOLLIN;
	event.data.fd=sfd;
	if(epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event)<0)
	{
		ERR_MSG("epoll_ctl");
	}
	printf("成功将sfd事件描述符挂载到红黑树上\n");


	char buf[256]="";
	int newfd=-1;
	while(1)
	{
		int ret=epoll_wait(epfd,events,10,-1);
		for(int i=0;i<ret;i++)
		{
			if(events[i].data.fd == sfd)
			{
				//获取连接成功后的新套接字
				newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
				if(newfd<0)
				{
					ERR_MSG("accept");
				}
				printf("[%s : %d] newfd=%d 客户端连接成功\n", \
						inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);

				//添加要检测的事件描述符
				event.events=EPOLLIN;
				event.data.fd=newfd;
				if(epoll_ctl(epfd,EPOLL_CTL_ADD,newfd,&event)<0)
				{
					ERR_MSG("epoll_ctl");
				}
				printf("成功将newfd:%d事件描述符挂载到红黑树上\n",newfd);
			}
			else
			{
				int cfd=events[i].data.fd;
				int len=read(cfd,buf,sizeof(buf));
				if(len<=0)
				{
					close(cfd);
					epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,NULL);
				}
				else
				{
					buf[len]='\0';
					printf("接收的数据:%s\n",buf);
					strcat(buf,"*-*");
					write(cfd,buf,sizeof(buf));
				}
			}

		}
	}

	close(newfd);

	//关闭文件描述符
	if(close(sfd) < 0)
	{
		ERR_MSG("close");
		return -1;
	}
	return 0;
}	

客户端:

复制代码
#include<myhead.h>
#define IP "192.168.250.100"
#define PORT 8888
int main(int argc, const char *argv[])
{
	//创建流式套接字
	int cfd=socket(AF_INET,SOCK_STREAM,0);
	if(cfd<0)
	{
		ERR_MSG("socket");
	}
	printf("socket success\n");

	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(PORT);
	sin.sin_addr.s_addr=inet_addr(IP);

	//连接服务器
	if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("connect");
	}
	printf("connect success\n");

	char buf[256]="";
	while(1)
	{
		memset(buf,0,sizeof(buf));
		printf("请输入发送的信息:");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]='\0';
		write(cfd,buf,sizeof(buf));

		int len = read(cfd, buf, sizeof(buf));
        if (len <= 0) 
		{
			ERR_MSG("read");
        } 
		printf("接收服务器返回的信息:%s\n",buf);
	}
	return 0;
}	

测试现象:

相关推荐
それども6 小时前
Gradle 构建疑难杂症 Could not find netty-transport-native-epoll-linux-aarch_64.ja
java·服务器·gradle·maven
NightReader7 小时前
CPU 高使用率,怎么降下来
运维·服务器
开开心心就好8 小时前
免费流畅的远程控制实用工具
linux·运维·服务器·网络·智能手机·excel
代码熬夜敲Q10 小时前
ENSP 网络工程实验
linux·运维·服务器
銳昊城10 小时前
项目七: 配置与管理Web服务器(2) C2
运维·服务器
Muyuan199810 小时前
30.通过Claude code做项目系统测试
运维·服务器·人工智能·fastapi
yyuuuzz10 小时前
aws的核心概念与常见使用场景
运维·服务器·网络·云计算·aws
赵药师10 小时前
dpkg: warning: files list file for package ‘libselinux1:amd64‘ missing;
linux·运维·服务器
zt1985q10 小时前
本地部署开源内容管理系统 Typemill 并实现外部访问
运维·服务器·开源
ElevenS_it18811 小时前
网络没完全断但业务已经受影响:「灰色故障」排查的完整方法论
运维·服务器·网络