项目架构梳理

  1. 本项目使用到的重点知识

    • 网络库
    • c++11的智能指针
    • 命名空间
    • 模板编程
  2. 类关系

    1. Server类
      服务器的抽象。其规定了服务器的运行模式,也就是MainLoop函数实现整体的循环,重写_RunLogic()函数,为运行逻辑,_Recycle为回收逻辑。_Init为初始化逻辑。这三者都是虚函数,并且构成了一个Server运行的主要的步骤。也就是初始化–> 运行 --> 回收资源

      1. _Init逻辑:

        1. TCPBind()对于一个server来说,创建一个tcp socket,并且绑定到一个本机的一个地址和端口上去,进行监听。其先利用这个本地的地址和端口创建一个ListenSocket类,这个类是可以完成一个socket的创建,绑定,监听,在accept到客户端的socket的时候,调用server的NewConnection()操作。

        小问题
        这里的ListenSocket类是怎样找到server实例的呐?
        这里采用了单例模式,我们创建了一个server之后,就只允许这一个server,不可以创建其他的server了。
        实现方式:

        1. 设置一个private的静态Server指针,指向唯一的实例
        2. 设置一个静态方法来返回这个唯一实例
        3. 在构造函数中,如果这个实例指针为NULL,那么就创建一个实例。如果不为NULL,说明已经创建了第二个Server,就直接报错退出。当然,这是一种比较危险的做法。我们不如直接将构造函数删除掉,或者反倒private里面。提供一个静态方法用来制作一个实例,如果已经有这个实例的话,直接返回原来的值。如果没有的话,就创造。
      2. _RunLogic

        • 在Server.cc中定义的内容为 tasks_.DoMsgParse(); 利用了一个TaskManager的类对象。但是我么可以覆盖这个函数。也建议覆盖。在覆盖的时候,也是可以执行父类的函数来完成一些默认任务的。
        • 在Server类中有一个 _OnNewConnection的虚函数,这个函数在_RunLogic函数内会使用,但是需要进行自己定义,否则的话,执行原生(Server中的代码)代码,那么会进行提醒。然后什么都不会做。因此,我们需要从写这个代码,在代码中调用我们自己定义的对于StreamSocket的继承。
    2. SocketAddr类
      这个类主要是对于socketaddr_in 数据结构的封装,提供了 拷贝构造函数,赋值运算符重载(注意函数名,参数和返回值),构造函数(使用字符串进行构建,使用socketaddr_in结构体进行构建)
      这个类提供了各种方法,包括各种构造函数,判断是否为空,还重载了 == 运算符以及 != 运算符

    3. Socket类
      这个类为socket的封装。可以创建一个udp或者tcp的socket,可以设置各种socket属性,关闭socket的操作。

      • 可以设置socket选项(使用setsockopt()函数):
        • 设置TCP_BODELY会不使用Nagle算法。即使是很少的数据,也进行发送。会一定程度上提升体验,但是可能造成网络拥堵。
        • 设置SO_REUSEADDR,使得处于time_wait状态的socket端口可以被及时利用。这个选项还有其他的功能。
      • 这个类还提供了很多可以操作socket的api,通过静态函数的实现方法来实现。表示不依赖于对象。
      • socket类的包裹对象localsocket 为protected 的。他没有构造函数可以将这个localsocket赋值。但是这个类可以被继承,然后使用子类的构造函数来进行赋值。说明socket这个类往往是不会代表一个独立的对象的。
    4. StreamSocket类就是Socket的继承,其是关于tcp的实现.是对于tcp链接的模拟
      StreamSocket是关注于整个tcp连接,也就是包括了服务端和客户端。

      • 有了peer,也就是对方的地址,可以完成发送数据包的任务,并且定义了onreadable,onWriteable()函数等来进行监督
      • 其有一个**纯虚函数_HandlePacket(),**用来处理数据包。也就是读取到的数据包。StreamSocket提供了作为一个已经建立的tcp连接socket可以完成的肯定的动作。但是,又留下了具体的处理的空间,让子类去实现自己的处理逻辑。
    5. ListenSocket也是Socket的子类,其代表一个处于监听状态的socket。其主要的功能是通过成员函数Bind来进行设置的。一个Listensocket代表一个处于监听状态的socket实体,已经经过了socket,bind,listen函数了。Bind函数会创建一个local_socket,然后进行一些设置。Accept函数会执行accept的功能,然后将client的地址存储进这个类中的一个成员里面。

      • ListenSocket类其实代表一个服务器本地监听socket。StreamSocket代表一个连接到的对端的TCP socket。两个类都属于socket,因此都继承了Socket类。Socket类体现了两者之间的共同点。凡是Socket,都有可读OnReadable(),可写OnWriteable(),出错OnError(),Onconnect(), OnDisConnect()的行为。比如,对于ListenSocket来说,其可读就是代表有连接来了;对于StreamSocket来说,其可读就代表对端发来信息了。
    6. NetThreadPool是一个网络线程池的类。

      • 其不是采用单例模式。其构造函数采用默认的构造函数,也就是没有给private数据成员recvThread和sendThread赋值的能力。其有静态函数,Instance,也可以返回一个对象。
      • 他依赖NetThread类, RecvThread和SendThread类,后两者是NetThread的子类。
      • NetThread类依赖Poller类,Poller类对象作为NetThread的一个成员而存在。
    7. Log/Logger.h 文件中定义了日志功能相关的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值