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;
}	

测试现象:

相关推荐
yeyuningzi1 分钟前
Debian 12环境里部署nginx步骤记录
linux·运维·服务器
EasyCVR1 小时前
萤石设备视频接入平台EasyCVR多品牌摄像机视频平台海康ehome平台(ISUP)接入EasyCVR不在线如何排查?
运维·服务器·网络·人工智能·ffmpeg·音视频
城南vision1 小时前
计算机网络——HTTP篇
网络协议·计算机网络·http
龙哥说跨境2 小时前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
懒大王就是我3 小时前
C语言网络编程 -- TCP/iP协议
c语言·网络·tcp/ip
pk_xz1234564 小时前
Shell 脚本中变量和字符串的入门介绍
linux·运维·服务器
小珑也要变强4 小时前
Linux之sed命令详解
linux·运维·服务器
海绵波波1074 小时前
Webserver(4.3)TCP通信实现
服务器·网络·tcp/ip
九河云6 小时前
AWS账号注册费用详解:新用户是否需要付费?
服务器·云计算·aws
Lary_Rock6 小时前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器