《Linux多线程服务端编程》—muduo网络库(1)

TCP网络编程本质论

思维转换:

把原来“主动调用recv(2)来接收数据,主动调用accept(2)来接受新连接,主动调用send(2)来发送数据”的思路转换为“注册一个收数据的回调,网络库收到数据会调用我,直接把数据提供给我,供我消费。注册一个接受连接的回调,网络库接受了新连接会回调我,直接把新连接对象传给我,供我使用。需要发送数据的时候,只管往连接中写,网络库会负责无阻塞地发送。”

作者(陈硕)认为,TCP网络编程最本质的是处理三个半事件:

1.连接的建立,包括服务端接受(accept)新连接和客户端成功发起(connect)连接。TCP连接一旦建立,客户端和服务端是平等的,可以各自收发数据。

2.连接的断开,包括主动断开(close、shutdown)和被动断开(read(2)返回0)。

3.消息到达,文件描述符可读。这是最为重要的一个事件,对它的处理方式决定了网络编程的风格(阻塞还是非阻塞,如何处理分包,应用层的缓冲如何设计等等)。

3.5 消息发送完毕,这算半个。对于低流量的服务,可以不必关心这个事件;这里的“发送完毕”,是指将数据写入操作系统的缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对方已经收到数据。

Reactor模式

Reactor 是一种事件驱动机制。它和普通函数调用的不同之处在于:应用程序不是主动的调用某个API完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的时间发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”

moduo库Reactor模式的实现

muduo主要通过3个类来实现Reactor模式:EventLoop,Channel和Poller。

1. EventLoop

EventLoop是一个主控类,是一个事件发生器,它驱动Poller产生/发现事件,然后将事件派发到Channel处理。moduo的线程模型为 one loop per thread,即每个线程只能有一个 EventLoop 对象。EventLoop对象的生命周期通常和其所属的线程一样长。

主要数据成员:

    const pid_t threadId_; //保存当前EventLoop所属线程id

    boost::scoped_ptr<Poller> poller_; //实现I/O复用 

    boost::scoped_ptr<TimerQueue> timerQueue_;

    int wakeupFd_;

    boost::scoped_ptr wakeupChannel_; //用于处理wakeupFd_上的可读事件,将事件分发到handlRead()

    ChannelList activeChannels_; //有事
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值