Muduo网络库学习笔记之:TcpServer接受新连接

本篇 博文主要讲muduo中三个半事件的新连接的建立。
先来看一下流程图,看不懂?没关系,请听我一一道来:
Muduo网络库学习笔记之:TcpServer接受新连接
最前面两个EventLoop和Channel在我的前两篇博文里面已经讲的足够详细了,到目前为止都还看不懂的同学请移步前两篇博文复习一下。

loop监听linsten套接字,当linsten套接字有可读事件的时候调用Channel的handleEvent()转而调用Acceptor的handleRead()。Acceptor是个新的类,之前没提到过,听名字来看,这个类应该是封装了accept(2)函数。用于接收新连接。现在我们就来介绍一下这个类吧:

Acceptor

Muduo网络库学习笔记之:TcpServer接受新连接
Muduo网络库学习笔记之:TcpServer接受新连接
Muduo网络库学习笔记之:TcpServer接受新连接
这个类是一个内部类,对用户而言没有接口,它仅仅供TcpServer使用。这里要顺便提一下TcpServer,不然Accpetor类讲不下去。TcpServer是一个用户层的类,在用户层,用户只需要创建一个EventLoop,然后创建一个TcpServer,把EventLoop和InetAddress(对于struct sockaddr_in 的封装,用于创建Tcp端口)传进去就行。并且在TcpServer里面设置事件处理逻辑函数(回调)就可以了。

Acceptor的构造函数执行创建TCP服务端的传统步骤,即socket(2),bind(2),listen(2)等Sockets API。以及设置listen Fd的可读事件回调函数即handleRead(),后者会调用accpet(2)并回调newConnetionCallback_。
Muduo网络库学习笔记之:TcpServer接受新连接
这里抛出一个问题,假如文件描述符用完了怎么把?

newConnetionCallback_是哪里来的呢?当然谁拥有此对象谁就负责给它的成员变量赋值拉,之前提到了Accpetor是TcpServer的一个内部类,那么newConnetionCallback_便是Tcpserver传值的咯。

Tcpserver

TcpServer是一个用户层的对象,它的生命周期由用户控制。Accptor 接收到新连接后将clientFd通过newConnetionCallback_回调函数(也就是TcpServer::newconnetion())传递给Tcpserver。后者会创建TcpConnection对象conn,把它加入到ConnectionMap,设置好Callback,再调用conn->connecEstablished().又提到了一个新的类TcpConnection对不对,别急,这些都是会慢慢讲到的。

Muduo网络库学习笔记之:TcpServer接受新连接
在TcpConnection::connectEstablished()中,调用channel的disableReading()更新EventLoop的监听对象,也就是把此Channel添加到EventLoop的监听对象中。
至此,一个TCP新连接就算完成了。当这个客户端有可读/可写事件的时候会再次调用poll来处理相关事件。