muduo编程示例2019-11-02

muduo编程示例2019-11-02
图片发自简书App

//discard 长连接应用层协议,关注:消息/数据到达事件。

void DiscardServer::onMessage(const TcpConnectionPtr& conn,

                              Buffer* buf,

                              Timestamp time)

{

  string msg(buf->retrieveAllAsString());

  LOG_INFO << conn->name() << " discards " << msg.size()

          << " bytes received at " << time.toString();

}

daytime 短连接协议,发送完后,服务器主动断开。关注连接已建立事件。

void DiscardServer::onConnection(const TcpConnectionPtr& conn)

{

  LOG_INFO << "DiscardServer - " << conn->peerAddress().toIpPort() << " -> "

          << conn->localAddress().toIpPort() << " is "

          << (conn->connected() ? "UP" : "DOWN");

}

time 返回一个32-bit的整数。表示从1970-01-01 00:00:00Z到现在的秒数。关注连接已建立事件。

void TimeServer::onConnection(const muduo::net::TcpConnectionPtr& conn)

{

  LOG_INFO << "TimeServer - " << conn->peerAddress().toIpPort() << " -> "

          << conn->localAddress().toIpPort() << " is "

          << (conn->connected() ? "UP" : "DOWN");

  if (conn->connected())

  {

    time_t now = ::time(NULL);

    int32_t be32 = sockets::hostToNetwork32(static_cast<int32_t>(now));

    conn->send(&be32, sizeof be32);

    conn->shutdown();

  }

}

chargen协议只发送数据,不接收数据。关注消息/数据发送完毕事件。

void ChargenServer::onConnection(const TcpConnectionPtr& conn)

{

  LOG_INFO << "ChargenServer - " << conn->peerAddress().toIpPort() << " -> "

          << conn->localAddress().toIpPort() << " is "

          << (conn->connected() ? "UP" : "DOWN");

  if (conn->connected())

  {

    conn->setTcpNoDelay(true);

    conn->send(message_);

  }

}

void ChargenServer::onMessage(const TcpConnectionPtr& conn,

                              Buffer* buf,

                              Timestamp time)

{

  string msg(buf->retrieveAllAsString());

  LOG_INFO << conn->name() << " discards " << msg.size()

          << " bytes received at " << time.toString();

}

void ChargenServer::onWriteComplete(const TcpConnectionPtr& conn)

{

  transferred_ += message_.size();

  conn->send(message_);

}


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App

muduo把主动关闭连接这件事分为两步,如果主动关闭连接,它会先关闭写端,等对方关闭之后,再关本地的读端。

Tcpconnection对象析构的时候,正式关闭。

可以从/proc/pid/fd中查找没有关闭的文件描述符。

Buffer

muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App


muduo编程示例2019-11-02
图片发自简书App

设计目标:开发公司内部分布式程序。

 网络编程使用Protobuf需要解决两个问题:长度,类型。

长度:Protobuf打包数据没有自带长度信息或终结符,需要有应用程序自己在发生和接受的时候做正确的切分。

类型:Protobuf打包的数据没有自带类型信息,需要由发送方把类型信息传给接收方,接收方创建具体的Protobuf Message对象,再做反序列化。

长度:通常在每个消息前面加固定长度的length header.

类型:Protobuf对此有内建的支持。

一种做法是:Protobuf data之前加上header,header中包含消息长度和类型信息。

类型信息的“山寨”做法主要两种:

1、在header中放int typeId,接收方用switch-case来选择对于的消息类型和处理函数;

2、在header中放string typeName,接收方用look-up table来选择对应的消息类型和处理函数。