逐步实现TCP服务端Step03-15:小结

这是一个里程碑,到目前为止,基本的构件都已实现,为下一步的扩展打下了基础。

所谓的“扩展”是指把对单个客户的服务扩展为对n个客户,目前这个版本只针对一个客户。

再明确一下目标,我们要实现的是一个暂时不关注具体业务的基于TCP连接的后端系统。所谓的“不关注具体业务”,就是说要做的“抽象”一些。它更像是一个骨架,如果需要的话,可以把具体的业务逻辑填充进去。

为了让整个流程能运转起来,我们设定了一个简单的“回声”业务,即:把client发来的字符串,原封不动地返回去。

回顾演变过程,只列举几个关键节点。注意,send buf里的字节在发送的时候,实际只会被拷贝到TCP缓冲区,不会被删除。图中删除了那些被send掉的字节是为了方便说明。另外,图中使用的函数或变量名字跟代码中的名字可能略有不同。

原始阶段。单进程单线程,直接使用socket系列函数做简单的收发操作。

关注字节流的处理。一次recv调用未必能取到应用层所期望的全部字节,send调用也有同样的问题。对这二者进行封装,得到RecvOneMessage和SendOneMessage 。这两个函数的处理粒度均为消息,即:应用层收发的基本单位。

排除阻塞。单进程单线程模型的问题是,它只有一条“线路”,若前面发生了阻塞,后面就得做无谓的等待。目前能引起阻塞的就是基于socket的recv和send操作,将socket改为非阻塞类型。

考虑到对业务的处理,需要对服务进行拆分。处理业务的时候可能需要大量的计算或者I/O操作,总之会耗费大量的时间,从而影响到数据的收发工作。主要问题还是出在单进程单线程模型上,要把“网络通信”与“业务处理”放到两条“线路”上来做才合理。可以在单个进程中开两个线程,也可以使用两个单线程的进程,为简化开发,使用后一个方案,IPC使用共享内存(SHM)的方式来做。

整理、封装。基于C++面向对象特性对代码进行封装。得出CodeQueue,Message,TCPSocket,SharedMemory等基本构件,方便维护及扩展。



<==  index  ==>