2022-3-4

epoll

实现多路IO转接

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<ctype.h>

int main((int argc, char *argv[]){
	int i,n,j;
	int listenfd,connfd,efd,res,nready;
	struct epoll_event tep,ep[OPEN_MAX];
	char buf[BUFSIZ];

	struct sockaddr_in clie_addr, serv_addr;
	socklen_t clie_addr_len;
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	int opt=1;
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	bzero(&serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port= htons(9527);
	
	bind(listenfd, (struct sockaddr *) serv_addr, sizeof(serv_addr));
	listen(listenfd,128);
	efd = epoll_creat(OPEN_MAX);
	if(efd==-1)
		perr_exit("creat erro");
	tep.event = EPOLLIN;
	tep.data.fd = listenfd;
	res=epoll_ctl(efd, EPOLL_CTL_ADD, listenfd, &tep);
	if(res==-1)
		perr_exit("epoll_ctl erro");
	while(1){
		nready = epoll_wait(efd, &ep, OPEN_MAX, -1);
		if(nready == -1)
			perr_exit("epoll_wait erro");
		for(i=0;i<nready;++i){
			if(!ep[i]&EPOLLIN)
				continue;
			if(ep[i].data.fd==listenfd){
				clie_addr_len = sizeof(clie_addr);
				connfd = accept(listenfd, (struct sockaddr *) clie_addr, clie_addr_len)
				tep.event = EPOLLIN;
				tep.data.fd= connfd;
				res = epoll_ctl(efd, EPOLL_CTL_ADD, connfd, &tep);
				continue;
			}
			n = read(ep[i].data.fd, buf, sizeof(buf));
			if(n==0){
				res = epoll_ctl(efd, EPOLL_CTL_DEL, ep[i].data.fd, NULL);
				close(ep[i].data.fd);
			}
			for(j=0;j<sizeof(buf);++j){
				buf[j]=toupper(buf[j]);
			}
			write(ep[i], buf, n);
		}
		
	}
}

边沿触发和水平触发

就是模电里的知识,epoll默认是水平触发,也就是只要还有消息就会触发epoll_wait,边沿触发是有消息来才进行一次触发
在这里插入图片描述
如上图,管道内子程序写东西,一次写了10字节,“aaaa\nbbbb\n”,但是父进程读的时候一次读5个,也就是第一次读“aaaa\n”,这时管道内还有bbbb\n存在,如果是水平触发的话,读完第一次“aaaa\n”后,重新进行while循环的时候还是会触发epoll_wait,进行第二次读取,如果是边沿触发则不会在第二次while循环的时候读取了,直到子程序向管道内写入新的东西的时候才会读取bbbb\n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值