一个网络处理通常是我们通过epoll接收读事件,然后从网络层读取数据放入缓存中,在从缓存中读出数据,进行协议解析分发处理消息。一个消息过来通常是需要进行应答的,所以我们还需要将回复信息进行封包发送到网络层。
1、网络接收相对比较慢,消息传递情况比较复杂,我们通常是需要进行缓存,然后分发,linux下通常是使用epoll进行消息接收。
2、缓存需要很好的设计,尽量防止多次拷贝处理。
3、通常网络处理都是多线程的方式。
(1)1、一种方式是通过多个epoll进行消息接收,一个epoll占用一个线程。
2、或者一个主epoll进行连接处理,接收到消息读写事件后,将描述符分发给各个子epoll 进行socket 读写处理,每个子epoll是一个线程。
3、也可以一个epoll进行连接,等待事件响应,一旦有读写事件就将其插入事件队列,然后一个线程里循环处理事件队列,也可以开多个线程处理事件队列。(libevent实现方式)
(2)缓存可以设计成池,提前分配好内存,如果消息是固定长度的,直接一次性分配好,如果不固定长度,则可以使用链表缓存的方式,分配多个固定长度地址块,根据消息进行依次分配,这种方式比较好的解决了,分配一个大内存需要不断进行移动拷贝的处理。
(3)消息分发,这个其实也可以设计成多线程进行消息处理,可以根据连接进行hash,每个session都有一个唯一id,hash(id)%(线程数)然后给到不同的线程进行消息处理。做成任务线程池。
一个网络库可以分为几个模块(内存分配模块缓存池管理、epoll模块、session连接管理、dispatch任务分发处理)
读者可以参考一下我自己的网络库设计实现方式: