逐步实现TCP服务端Step04-5:内存管理

这里要说的不是操作系统层面的内存管理,而是在netio及s中对对象实施的管理。之前实现的那些类大多重载了new运算符,在实例化时实际使用的是从共享内存中分配的一块空间。这块共享内存是事先创建好的一块足够大的空间,通过计算相关对象的尺寸,及运行时最多会创建的对象的个数可以得出这块共享内存的大小。

下图为目前为止各类间的静态关系 ...


逐步实现TCP服务端Step04-4:令Control更抽象

直接继承自Control的NControl和SControl代表了两种主控类,一种专注于通信,另一种则不需要通信。对专注于通信的类而言,Recover功能并非必要,不支持通信的主控类因不与client直连,可在client无感的情况下重启进程,此时的Recover功能是必要的。要实现Recover,主控类就需要构建在一块共享内存之上。

简单地说,在Control的基础之上,NControl要实现一套与通信相关的方法及属性且不需要SharedMemory属性,SControl需要SharedMemory属性,与通信相关的内容一律不要。

按照目前的设计,假设NControl自己实现了一个用于通信的方法,若想通过g_ncontrol直接调用到该方法的话 ...


逐步实现TCP服务端Step04-3:封装netio主逻辑

之前对代码做整理封装的时候,并没过多地考虑netio,当时的关注点在s上,只对s做了封装,现在对netio做类似的处理。

s与netio的主逻辑中有不少类似的地方,如使用共享内存,操作c2s_code_queue和s2c_code_queue等等。这些基础操作应被整合在Control类中,由于Control这个名字在处理s的时候已被使用,这里需要改下名字,将对应于s的Control类改为SControl,对应于netio的Control类命名为NControl,而Control则为它们共同的父类。

无论s还是netio,大流程可概括为三步:初始化 ...


逐步实现TCP服务端Step04-2:处理client断开

当某个client断开连接时,后端系统要做相应的“清理”工作。具体说来就是netio要销毁TCPSocket对象,s要销毁用户对象。

问题在于,client断开连接,s是不知道的,除非netio以某种方式告知它。

可以在c2s_code_queue中push一个特殊的code以表明某个client已经离线了。这样,一旦s取到该code就触发”清理“操作。

这个特殊的code其实不用专门去设计。考虑一下client断开时,TCP的做法是向对端发送一个不携带数据的报文段 ...


逐步实现TCP服务端Step04-1:改造

目前的这版程序不支持多客户并发,并非由于结构的局限性导致的无法实现。而是由于在早期不想引入不相关的复杂度而故意没去做这部分内容。

现在进行改造。主要修改netio,将监听socket置为非阻塞,让accept也参与到主循环中来。另外,还需要一个容器来存放那些已被accept了的新socket 。

这个容器要能方便地删除元素(客户离线),同时支持随机访问。基于数组存储的链式结构可以满足需求。

基于C++模板实现了一个不关注元素具体类型的List类 ...


逐步实现TCP服务端Step04:应对多客户

先考虑一下现实生活中,“服务方”是如何为多个客户提供服务的。以去菜市场买菜为例说明,卖菜的商家为服务提供方。

常见的情形是数个客户站在摊位前与商家进行交易,一次完整的交易通常有三个步骤:客户向商家询价(下单),商家交货,客户付款。

这里不必纠结于客户的组织形式,是排队还是怎么样,这不在商家的业务范围内 ...