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

测试现象:

相关推荐
m0_7381207236 分钟前
应急响应——知攻善防靶场Linux-1详细应急过程
linux·运维·服务器·网络·web安全·ssh
Guistar~~36 分钟前
【Linux驱动开发IMX6ULL】WS73 驱动移植的详细教程基于USB协议--WIFi网卡、蓝牙BLE、星闪SLE
linux·驱动开发
GHL2842710901 小时前
无法连接服务端socket
linux·服务器·网络
kylezhao20191 小时前
S7-1200 CPU 与 S7-200 SMART S7通信(S7-1200 作为服务器)
运维·服务器
阿华hhh1 小时前
项目(购物商城)
linux·服务器·c语言·c++
摸鱼仙人~1 小时前
大模型文章生成的风格个性化与多文体写作:一套可落地的方法论
linux·运维·服务器
爬山算法2 小时前
Hibernate(30)Hibernate的Named Query是什么?
服务器·前端·hibernate
AC赳赳老秦2 小时前
Shell 脚本批量生成:DeepSeek 辅助编写服务器运维自动化指令
运维·服务器·前端·vue.js·数据分析·自动化·deepseek
学Linux的语莫2 小时前
linux的root目录缓存清理
linux·运维·服务器