muduo实现聊天服务器
muduo实现一个聊天室服务器,客户发送的消息将广播到连入的所有客户(包括自己)。
1.消息编码
消息的字节流定义成这种形式 0xXX 0xXX 0xXX 0xXX XXXXXX,前面四个字节表示消息的长度,后面是消息实体,在服务器收到消息后,需要将该消息解码,把前面四个字节的长度信息剥离,把消息发送出去。
muduo作者选择自己编写一个编解码器LengthHeaderCodec,用来解决头部信息的编解码,当已连接套接字可读时,muduo的TcpConnction会读数据并存入input buffer中,然后回调用户的函数。通过LengthHeaderCodec这一层封装,让用户代码只关心“消息到达”而不是“数据到达”。
//muduo/examples/asio/chat/codec.h
#ifndef __CODEC_H__
#define __CODEC_H__
#include<muduo/base/Logging.h>
#include<muduo/net/Buffer.h>
#include<muduo/net/Endian.h>
#include<muduo/net/TcpConnection.h>
class LengthHeaderCodec:boost::noncopyable
{
public:
typedef boost::function<void (const muduo::net::TcpConnectionPtr&,
const muduo::string& message,
muduo::Timestamp)> StringMessageCallback; //回调类型
//构造函数
explicit LengthHeaderCodec(const StringMessageCallback& cb)
:messageCallback_(cb)
{
}
void onMessage(const muduo::net::TcpConnectionPtr& conn,
muduo::net::Buffer* buf,
muduo::Timestamp receiveTime)
{
while (buf->readableBytes() >= kHeaderLen) // kHeaderLen == 4
{
// FIXME: use Buffer::peekInt32()
const void* data = buf->peek();//读取长度
int32_t be32 = *static_cast<const int32_t*>(data); // SIGBUS
const int32_t len = muduo::net::sockets::networkToHost32(be32);
if (len > 65536 || len < 0)
{
LOG_ERROR << "Invalid length " << len;
conn->shutdown(); // FIXME: disable reading
break;
}
else if (b

本文详细介绍了如何使用muduo库实现一个聊天服务器,包括消息编码、服务器实现(单线程Reactor、多线程Reactor)和客户端实现。muduo的LengthHeaderCodec处理消息头部,实现消息到达而非数据到达的处理。测试环节验证了消息广播和线程模型的正确性。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



