整个网络模型分为两个层次,一个是网络消息层(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来回调的时候,有可能发现我有很多包要发,或是因为其他网络原因,包积攒了很多,那么就要把这些包有顺序的放在队列中,一个一个的有序的发出去。如果一个包很大,一次发不完,怎么办?那也只能通过本地的缓存调整,最终发送完。不过一般会规定最大的包长的。
至于逻辑层的主循环,就很简单了,因为它只要处理被动的接受包的逻辑,这个时候,不管逻辑层的分层多么的详细,都无所谓了,思路已经很清晰了!
写完这篇文章,还有个道理就是鼓励下自己:今天搞不懂的代码,明天可以搞懂,明天不行,后天,总有一天搞懂的,相信自己最重要!