focus on linux, c/c++, lua

Epoll网络模型总结

整个网络模型分为两个层次,一个是网络消息层(Epoll), 一个是逻辑层。这两层开两个线程同时进行。当socket连接服务器成功之后,在epoll维护的事件队列中,加入该socket,并标记其当前为已连接状态,可以进行发送或是接受消息。下面针对Send和Recv两个分别描述。
首先epoll会在主循环中轮询新建立的链接,如果有新的链接,则执行链接动作,(逻辑层在链接时,有时候也需要做一些事情,可提供接口回调)。
1,Recv,接收网络消息为被动动作。只能由epoll的主循环驱动。当epoll检测到某个socket接收到新的数据时,connection把其中的数据取出来,放在本地缓存,并对其进行判断,是否是一个完整的包,根据tcp的滑动窗口协议,socket的一次recv的数据可能并不是像逻辑层想象的那样,一次就发一个完整的包,要对包进行判断和处理。 如果在connection中,收到并判断是一个完整的包。则把该包的数据,加入到逻辑层的数据队列,让逻辑层去处理。
2,Send, Send不同与Recv,Send是主动事件,由逻辑层的某发送接口触发,所以在connection中要提供一个循函数(Send)给逻辑层回调。首先把要发送的数据,放在本地缓存,让后修改当前socket的状态,告诉Epoll我有数据要发送,让Epoll来回调我的发送接口。Epoll来回调的时候,有可能发现我有很多包要发,或是因为其他网络原因,包积攒了很多,那么就要把这些包有顺序的放在队列中,一个一个的有序的发出去。如果一个包很大,一次发不完,怎么办?那也只能通过本地的缓存调整,最终发送完。不过一般会规定最大的包长的。
至于逻辑层的主循环,就很简单了,因为它只要处理被动的接受包的逻辑,这个时候,不管逻辑层的分层多么的详细,都无所谓了,思路已经很清晰了!

写完这篇文章,还有个道理就是鼓励下自己:今天搞不懂的代码,明天可以搞懂,明天不行,后天,总有一天搞懂的,相信自己最重要!

posted on 2010-06-10 10:40 zuhd 阅读(1355) 评论(1)  编辑 收藏 引用 所属分类: server

评论

# re: Epoll网络模型总结[未登录] 2012-01-17 11:22 冷锋

我用的epoll ET模式,我的recv跟你一样,但是Send的有点区别,我是在逻辑线程里面尝试直接发送,先判断下发送队列是否为空,如果为空的话那么直接发送,当然这里可能遇到发不完的情况,因此要记录下发送的位置,然后丢到发送队列中,IO线程里面,在可写事件到来时去检查队列并发送队列的数据。

PS:
IO线程通知逻辑线程我是通过条件变量,有点好奇你在逻辑线程是怎么通知IO线程的,IO线程应该已经在epoll_wait了,你是弄了个管道什么的吗?像memcached那样的做法。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理