Linux编程之epoll示例

基础原理理解请参考这篇:

IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

select主要解决的问题:(详细请参考:select用法&原理详解(源码剖析))

select/epoll区别:如果这篇文章说不清epoll的本质,那就过来掐死我吧!

逻辑框架

epoll处理框架

服务端:

//服务端 gcc server_epoll.c -o server_epoll
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  

#define true 				1
#define false				0
#define MAX_EVENT_NUMBER 	1024
#define BUFFER_SIZE 		10

/*将文件描述符设置为非阻塞*/
int setnonblocking(int fd)
{
	int old_option = fcntl(fd, F_GETFL);
	int new_option = old_option | O_NONBLOCK;
	fcntl(fd, F_SETFL, new_option);
	return old_option;
}

/*将文件描述符fd上的EPOLLIN注册到epollfd指示的epoll内核事件表中。 参数enable_et 指定是否对fd采用ET模式*/
void addfd(int epollfd, int fd, int enable_et)
{
	struct epoll_event event;
	event.data.fd = fd;
	event.events  = EPOLLIN;
	if(enable_et){
		event.events |= EPOLLET;
	}
	epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event );
	setnonblocking(fd);
}
/*LT 模式的工作原理*/
void lt(struct epoll_event *events, int number, int epollfd, int listenfd)
{
	char buf[BUFFER_SIZE];
	int i = 0;
	for(i= 0;i= 0);
	
	ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
	assert(ret != -1);
	
	ret = listen(listenfd, 5);//监听队列最多容纳5个
	assert(ret != -1);
	
	
	struct epoll_event events[MAX_EVENT_NUMBER];
	int epollfd = epoll_create(5);
	assert(epollfd != -1);
	
	addfd(epollfd, listenfd, true);
	while(1){
		int ret = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
		if(ret<0){
			printf("epoll failure\n");
			break;
		}
		lt(events, ret, epollfd, listenfd);
		//et(events, ret, epollfd, listenfd);
	}
	close(listenfd);
	return 0;
}

客户端:

//客户端 gcc client.c -o client
#include  
#include  
#include  
#include  
#include  
#include  
#include 
#include 

int main() 
{ 
    int client_sockfd; 
    int len; 
    struct sockaddr_in address;//服务器端网络地址结构体 
     int result; 
    char ch = 'A'; 
    client_sockfd = socket(AF_INET, SOCK_STREAM, 0);//建立客户端socket 
    address.sin_family = AF_INET; 
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(8888); 
    len = sizeof(address); 
    result = connect(client_sockfd, (struct sockaddr *)&address, len); 
    if(result == -1) 
    {
         perror("oops: client2"); 
         exit(1); 
    }
	printf("client_sockfd = %d\n", client_sockfd); 
    //第一次读写
    write(client_sockfd, &ch, 1);
	printf("first client write over!\n");
    read(client_sockfd, &ch, 1);
	printf("first client read over!\n");
    printf("the first time: char from server = %c sleep 5s\n", ch); 
    sleep(5);
    
    //第二次读写
    write(client_sockfd, &ch, 1);
	printf("second client write over!\n");
    read(client_sockfd, &ch, 1); 
	printf("second client read over!\n");
    printf("the second time: char from server = %c\n", ch);
    
    close(client_sockfd);
   
    return 0; 
}

执行结果:

Linux编程之epoll示例_第1张图片

你可能感兴趣的:(Linux-C编程,epoll)