LT模式&ET模式

LT:在数据到达之后,无论程序是没有接收,还是接收了,但没有接收完,下一轮epoll_wait仍然会提醒应用程序该描述符上有数据,知道数据被接收完。

ET:在数据到达之后,无论程序是没有接收,还是接收了,但是没有接收完,都只提醒一次,下一轮不再提醒应用程序该描述符上有数据。

同一事件仅仅被触发一次

ET的实现:

#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/epoll.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<errno.h>
#include<fcntl.h>
#define SIZE 100
void SetNonBlock(int fd)//将文件描述符设置成非阻塞的
{
	int old=fcntl(fd,F_GETFL);
	int new=old | O_NONBLOCK;
	fcntl(fd,F_SETFL,new);//将new设置到fd上
}
int Create_Socket()
{
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	assert(sockfd!=-1);
	struct sockaddr_in ser;
	memset(&ser,0,sizeof(ser));
	ser.sin_family=AF_INET;
	ser.sin_port=htons(6000);
	ser.sin_addr.s_addr=inet_addr("127.0.0.1");
	int res=bind(sockfd,(struct sockaddr*)&ser,sizeof(ser));
	assert(res!=-1);
	listen(sockfd,5);	
	return sockfd;
}
void et(int fd,struct epoll_event event,int epollfd)
{
	if(event.events&EPOLLRDHUP)
	{
		close(fd);
		epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,NULL);
		printf("%d client break link;\n",fd);
	}
	else if(event.events&EPOLLIN)
	{
		printf("%d S data is:\n", fd);
		while(1)
		{
			char buff[128]={0};
			int n=recv(fd,buff,5,0);
			if(n<=0)
			{
				if(errno==EAGAIN || errno==EWOULDBLOCK)
				{
					break;
				}
				close(fd);
				epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,NULL);
			}
			printf("%s",buff);
		}
		printf("\n");
		send(fd,"OK",2,0);
	}
	else
	{
	printf("error\n");
	}
}
void Deal_Link(struct epoll_event events[],int n,int sockfd,int epollfd)
{
	int i=0;
	for(;i<n;++i)
	{
		int fd=events[i].data.fd;
		if(fd==sockfd)
		{	
			struct 	sockaddr_in cli;
			int len=sizeof(cli);
			int c=accept(fd,(struct sockaddr*)&cli,&len);
			if(c<0)
			{
				printf("One client link error\n");
				continue;
			}
			SetNonBlock(c);
			struct epoll_event event;
			event.events=EPOLLIN | EPOLLRDHUP | EPOLLET;
			event.data.fd=c;
			epoll_ctl(epollfd,EPOLL_CTL_ADD,c,&event);
		}		
		else
		{
			et(fd,events[i],epollfd);
		}
	}
}

int main()
{
	int sockfd=Create_Socket();
	int epollfd=epoll_create(5);
	assert(epollfd!=-1);

	struct epoll_event event;
	event.events=EPOLLIN;
	event.data.fd=sockfd;
	epoll_ctl(epollfd,EPOLL_CTL_ADD,sockfd,&event);

	while(1)
	{
		struct epoll_event events[SIZE];
		int n=epoll_wait(epollfd,events,SIZE,-1);	
		if(n<=0)
		{
			printf("epoll wait error\n");
			continue;			
		}	

		printf("epoll wait return\n");
		Deal_Link(events,n,sockfd,epollfd);
		
	}
}

注意:

  • 文件描述符必须设置为非阻塞模式
  • 内核事件表上的文件描述符必须关注EPOLLIN事件
  • 当事件发生时,必须以循环的方式处理时间,知道事件处理完成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值