muduo网络库学习笔记(14):chargen服务示例

chargen简介

chargen(Character Generator Protocol)是指在TCP连接建立后,服务器不断传送任意的字符到客户端,直到客户端关闭连接。

它生成数据的逻辑如下:

for (int i = 33; i < 127; ++i)
{
    line.push_back(char(i));
}
line += line;

for (size_t i = 0; i < 127-33; ++i)
{
    message_ += line.substr(i, 72) + '\n';
}

其输出数据格式类似下图,每行有72个字符,完整的一组输出数据有95行:
这里写图片描述

在介绍muduo chargen服务示例前,我们需要了解muduo::TcpConnection是如何发送数据的。

TcpConnection发送数据

一、代码的改动
之前几篇博客介绍了TcpConnection关于连接建立和连接断开的处理,在此基础上,TcpConnection的接口中新增了两个函数send()和shutdown(),这两个函数都可以跨线程调用。其内部实现增加了sendInLoop()和shutdownInLoop()两个成员函数,并使用Buffer(muduo对应用层缓冲区的封装)作为输出缓冲区。

TcpConnection的状态也增加到了四个:

// 连接断开,连接中,已连接,断开连接中
enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };

TcpConnection接口的变化:

// send()有多种重载
void send(const void* message, size_t len);
void send(const StringPiece& message);
void shutdown(); 

......

void sendInLoop(const StringPiece& message);
void sendInLoop(const void* message, size_t len);
void shutdownInLoop();

Buffer outputBuffer_;  // 应用层发送缓冲区

发送数据会用到Channel的WriteCallback,且由于muduo采用Level Trigger(水平触发),因此我们只在需要的时候才关注可写事件,否则会造成busy loop。

Channel.h的改动如下:

void enableReading() { events_ |= kReadEvent; update(); }
void enableWriting() { events_ |= kWriteEvent; update(); }
void disableWriting() { events_ &= ~kWriteEvent; update(); }
void disableAll() { events_ = kNoneEvent; update(); }
bool isWriting() const { return events_ & kWriteEvent; }

二、源码分析
我们首先来看发送数据的TcpConnection::send()函数,它是线程安全的,可以跨线程调用。如果在非IO线程中调用,它会把message复制一份,传给IO线程中的sendInLoop()来发送。

代码片段1:TcpConnection::send()
文件名:TcpConnection.cc

void TcpConnection::send(const std::string& message)
{
  if (state_ == kConnected)
  {
    if (loop_->isInLoopThread())
    {
      sendInLoop(message);
    }
    else
    {
      loop_->runInLoop(
          boost::bind(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值