muduo网络库学习(三)

这章是做一个聊天服务器,聊天功能是一个最基础也最常见的功能。虽然简单,但是基本的设计思想和问题还是很全面的,我们来一步步分析。

TCP分包

TCP字节流协议上做应用层分包是网络编程的基本需求。
分包
在发送一个消息或者一帧数据的时候,通过一定的处理,让接收方能从字节流中识别并截取出一个个消息。其实就可以理解为标点符号,一堆文字不加标点符号(我今天不想出门去写了一个博客就不知道后面写什么了完全就是演示一下字节流是个啥东西),字节流中不加标点符号,就无法提取出消息,就像这个博客就是一个字节流,分包就是,句号表示一句结束。换行表示一段结束。
短连接TCP分包简单。断开连接后收不到信息后,read到0就是结尾了。
长连接TCP一般是四种方式:

  1. 消息长度固定,每次16个字节固定,就像我告诉你四个字一句,你按四个字断句就行。
  2. 用特殊字符或字符串作为消息的边界。http中headers以“\r\n”标志消息的结束。就像句号的作用。
  3. 在每条消息头部加一个长度字串。就是每次我告诉你我这句话有几个字。比如我说了15,然后你读取15个字这句结束。
  4. 利用消息本身的格式分包。就像用两个东西把一条消息圈在里面。

聊天服务
书里的协议是这样的:

  1. 服务端程序在端口listen新连接
  2. 客户端向服务端发起连接
  3. 连接后,客户端随时准备接收服务端的消息并在屏幕上显示出来
  4. 客户端接受键盘输入,以回车为界,将消息发送给服务端
  5. 服务端接收到消息后,依次发送给连接到的客户端,包括原发送客户端
  6. 一个服务端可以同时为几个客户端服务,当有消息到达后,会发送给每个客户端。但不指定顺序
  7. A先于B到达服务端,则客户端处A也先于B

消息格式

正如之前所说,我们要统一消息格式,怎么分包。本例采用第三种头部附加长度的方式。头部长度4个字节,以网络序存放,字符间没有间隙。
比如两条消息:“hello”,“yan+”,打包后就是17个字节:
0x00,0x00,0x00,0x05,‘h’,‘e’,‘l’,‘l’,‘o’,0x00,0x00,0x00,0x04,‘y’,‘a’,‘n’,’+’
打包代码将string message打包为muduo::net::Buffer,通过conn发送。
在这里插入图片描述
分包代码:
在这里插入图片描述
编解码器
在这里插入图片描述

服务端实现

在这里插入图片描述
先看一下数据成员,loop和server不必说,有一个解码器的成员,有一个set成员。
在这里插入图片描述在这里插入图片描述
构造函数里注册回调,前面已经提到过,需要注意的是,onmessgae注册给了server_,codec_注册stringmessage,也就是codec解析消息后回调给chatserver。通过一个简单的间接层来减少复杂度。
在这里插入图片描述
用shared_ptr处理连接的建立和断开,新连接加入,断开的连接删除。
在这里插入图片描述
处理消息的代码,遍历整个容器,将消息打包发给各个客户链接。
在这里插入图片描述
main函数不做介绍,熟悉的套路。

客户端的实现

客户端不同之处在于要读取键盘输入,而eventloop独占线程,所以需要使用两个线程,一个读输入,一个处理IO。
在这里插入图片描述
看一下构造函数里的注册回调,与前面一样,所以这个可以当作一个套路记住。
write会由main线程调用,所以要加锁,保护shared_ptr。在这里插入图片描述在这里插入图片描述
同样,eventloop线程调用onconnection,所以要加锁保护shared_ptr。
在这里插入图片描述
printf是线程安全的,不用cout的原因也是因为线程不够安全。
在这里插入图片描述在这里插入图片描述
main函数还是比较简单的,关键是client里面的loop是eventloopthread中的eventloop。
这章代码居多,所以时间耗费比较长。第七章比较难啃,加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值