C++从0实现Reactor高并发网络服务器 复习与回顾(1)
(8)封装Acceptor类和Connection类:Why?Channel类中封装了监听的fd和客户端连接的fd,但是二者的功能和生命周期是不同的(前者用于监听并且生命周期随着服务端程序,后者用于客户端连接服务器传输数据,客户端一旦断开生命周期也就终止)。因此我将他们分别封装起来,在Channel上再做一层封装,监听的Channel封装成Acceptor类,客户端连接的Channel封装成Connection类。
(9)优化回调函数<1>:当前我们的网络服务器的Channel类的newconnection函数中暂时接管着产生一个新连接的操作,也就是调用了刚刚创建的Connection类,但这样做是不合适的。Acceptor类和Connection类封装了Channel类,也就是Channel类是他俩的下层类,在网络服务程序中,监听的fd产生客户端的fd,Acceptor类中创建了监听的fd,因此应该由Acceptor类创建新连接。
改动就是把newconnection的函数从Channel类中搬到了Acceptor类。(回调函数的好用之处尽显!)
(10)优化回调函数<2>:Acceptor和Connection类是平级的,因此我们需要在TcpServer类中也创建Connection对象,并将在Acceptor类中创建的Connection对象(客户端新连上来的)的代码放在TcpServer类中(Acceptor类知道什么时候有客户端连上来创建它,但是不知道什么时候断开,无法释放)。这里也是用的回调函数。
(11)Connection对象的生命周期<上> :在以及写到这的代码中,会打印新连上来的客户端的IP地址和端口信息。这些信息应该跟随创建新的Connection一起打印,因此把这行代码放到TcpServer类中的newconnection的函数中(于此同时,在Socket类和Connection类中增加返回ip和端口的成员函数,从这里可以看出Socket类和Connection类都是属于比较底层的类)。
在TcpServer中还需要处理new出来的Connection对象。一个TcpServer对应一个Acceptor对象(监听)和多个Connection对象(连上来的客户端),因此我们需要一个数据结构来管理这些连上来的多个Connection对象。用map<fd,Connection对象指针>来存,每次new Connection的时候,就加入map,并在析构函数中释放map中的全部fd。