您的位置:首页 > 其它

基于EPOLL模型的局域网聊天室和Echo服务器

2017-11-09 10:54 309 查看
一、EPOLL的优点

在Linux中,select/poll/epoll是I/O多路复用的三种方式,epoll是Linux系统上独有的高效率I/O多路复用方式,区别于select/poll。先说select/poll的缺点,以体现epoll的优点。

select:

(1)可监听的socket受到限制,在32位的系统中,默认最大值为1024.

(2)采用轮询方式,当要监听的sock数量很大时,效率低。

(3)随着要监听socket数据的增加,要维护一个存放大量fd的数据结构,系统开销太大。

poll:

解决了可监听socket数据受限的问题(采用链表存储的方式),但是其他确定跟select一样,在有大量并发时,效率并不高。

epoll:

相对于select/poll方式,epoll最大的优点是把哪个fd发生的I/O事件通知我们,而不是像select/poll那样,只是知道有I/O事件发生,具体是哪些fd,并不知道,所以需要从头到尾轮询,而随着要监听的fd数量增加时,效率会变低,而且当只有几个活跃的fd时,这个低效率的缺点会更加明显。总结起来就是:

(1)没有最大可监听数量的限制

(2)效率并不会因为要监听数量的增加而变得低效率

(3)使用mmap文件映射内存来加快消息传递

二、EPOLL的ET模式和LT模式

LT模式,也就是水平触发(select/poll都是水平触发的)。什么意思呢?就是说,比如对于写操作,只要系统缓冲区还有空间可以写,就一直触发可写EPOLLOUT,而读操作,只要系统缓冲区还有未读的数据,就一直触发可读EPOLLIN。

而ET模式,就是边沿触发,边沿,类似于电子电路中的边沿概念。具体来说,有点复杂,请看下面:

对于读操作:

(1) 当buffer由不可读状态变为可读的时候,即由空变为不空的时候。

(2) 当有新数据到达时,即buffer中的待读内容变多的时候。

(3) 当buffer中有数据可读(即buffer不空)且用户对相应fd进行epoll_mod IN事件时。

对于写操作:

(1) 当buffer由不可写变为可写的时候,即由满状态变为不满状态的时候。

(2) 当有旧数据被发送走时,即buffer中待写的内容变少得时候。

(3) 当buffer中有可写空间(即buffer不满)且用户对相应fd进行epoll_mod OUT事件时(具体见下节内容)。

请看下面图示:

clock_t start_time = clock();
for(i=0; i<MAX_CLIENT_NUM; i++)
{
fd = socket(AF_INET, SOCK_STREAM, 0);
assert(fd != -1);

rc = connect(fd, (struct sockaddr *)&serv_addr, serv_addr_len);
assert(rc != -1);
fds[i] = fd;

bzero(message, MAX_BUF_SIZE);
rc = recv(fd, message, MAX_BUF_SIZE, 0);
printf("%s\n", message);
}

for(i=0; i<MAX_CLIENT_NUM; i++)
{
close(fds[i]);
}
printf("Total connections: %d, Test passed at: %.2f seconds\n", MAX_CLIENT_NUM, (double)(clock()-start_time)/CLOCKS_PER_SEC);


View Code

八、写在最后

上面所有的代码都可以在我的GitHub上找到。我的GitHub地址:https://github.com/wolf623/chat_epoll

参考:http://blog.chinaunix.net/uid-28541347-id-4296180.html

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

来自为知笔记(Wiz)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: