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

测试现象:

相关推荐
SUGERBOOM7 分钟前
【网络安全】网络基础第一阶段——第一节:网络协议基础---- OSI与TCP/IP协议
网络·网络协议·web安全
danplus16 分钟前
node发送邮件:如何实现Node.js发信功能?
服务器·node.js·外贸开发信·邮件群发·蜂邮edm邮件营销·邮件接口·营销邮件
BeyondESH30 分钟前
Linux线程同步—竞态条件和互斥锁(C语言)
linux·服务器·c++
wn53131 分钟前
【Go - 类型断言】
服务器·开发语言·后端·golang
hanniuniu1332 分钟前
详细解读,F5服务器负载均衡的技术优势
运维·服务器·负载均衡
PatrickYao04221 小时前
记一次安装discuz时遇到的错误
服务器
小宋10212 小时前
玩转RabbitMQ声明队列交换机、消息转换器
服务器·分布式·rabbitmq
m0_609000423 小时前
向日葵好用吗?4款稳定的远程控制软件推荐。
运维·服务器·网络·人工智能·远程工作
kejijianwen4 小时前
JdbcTemplate常用方法一览AG网页参数绑定与数据寻址实操
服务器·数据库·oracle
Karoku0668 小时前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构