c++网络库-----muduo库
·
muduo
muduo 是一个用 C++ 编写的高性能网络库,由陈硕开发,具有事件驱动、非阻塞 I/O 等特点,常用于构建高性能的网络服务器和客户端程序。结合你之前给出的错误信息,它与 muduo 库中的 EventLoop 类密切相关,下面为你详细介绍 muduo 库以及针对该错误的相关分析和解决办法。
这个库很好的封装了Tcpsocket模块的代码,让人在上层用得也非常优雅,采用事件驱动模型,借助 epoll 或 kqueue 等 I/O 多路复用技术,能够高效处理大量并发连。
TcpServer模块
TcpServer 类的主要功能包括:
- 监听端口:绑定指定的 IP 地址和端口号,开始监听客户端的连接请求。
- 管理连接:负责接受客户端的连接,创建和管理
TcpConnection对象,处理连接的建立、断开等事件。 - 事件处理:提供回调函数接口,允许开发者处理连接建立、消息接收、连接关闭等事件。
class InetAddress : public muduo::copyable
{
public:
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
};
class TcpServer : noncopyable
{
public:
enum Option
{
kNoReusePort,
kReusePort,
};
TcpServer(EventLoop* loop,
const InetAddress& listenAddr,
const string& nameArg,
Option option = kNoReusePort);
void setThreadNum(int numThreads);
void start();
///
当⼀个新连接建⽴成功的时候被调⽤
void setConnectionCallback(const ConnectionCallback& cb)
{
connectionCallback_ = cb;
}
///
消息的业务处理回调函数--
这是收到新连接消息的时候被调⽤的函数
void setMessageCallback(const MessageCallback & cb)
{
messageCallback_ = cb;
}
};
EvenLoop
EventLoop 主要负责:
- 事件循环:不断地循环检查并处理各种 I/O 事件(如可读、可写事件)和定时事件。
- 事件分发:将发生的事件分发给对应的处理函数进行处理。
- 线程绑定:
EventLoop是线程绑定的,即一个EventLoop实例只能在创建它的线程中运行,保证了线程安全性和事件处理的顺序性。
class EventLoop : noncopyable
{
public:
/// Loops forever.
/// Must be called in the same thread as creation of the object.
void loop();
/// Quits loop.
/// This is not 100% thread safe, if you call through a raw pointer,
/// better to call through shared_ptr<EventLoop> for 100% safety.
void quit();
TimerId runAt(Timestamp time, TimerCallback cb);
/// Runs callback after @c delay seconds.
/// Safe to call from other threads.
TimerId runAfter(double delay, TimerCallback cb);
/// Runs callback every @c interval seconds.
/// Safe to call from other threads.
TimerId runEvery(double interval, TimerCallback cb);
/// Cancels the timer.
/// Safe to call from other threads.
void cancel(TimerId timerId);
private:
std::atomic<bool> quit_;
std::unique_ptr<Poller> poller_;
mutable MutexLock mutex_;
std::vector<Functor> pendingFunctors_ GUARDED_BY(mutex_);
};
Tcpconnection
TcpConnection 主要负责:
- 连接管理:处理 TCP 连接的建立、断开和状态维护。
- 数据读写:提供数据的读取和发送功能,支持非阻塞 I/O 操作。
- 事件处理:处理连接上的各种事件,如连接建立、连接关闭、数据可读、数据可写等,并通过回调函数通知用户。
class TcpConnection : noncopyable,
public std::enable_shared_from_this<TcpConnection>
{
public:
/// Constructs a TcpConnection with a connected sockfd
///
/// User should not create this object.
TcpConnection(EventLoop* loop,
const string& name,
int sockfd,
const InetAddress& localAddr,
const InetAddress& peerAddr);
bool connected() const { return state_ == kConnected; }
bool disconnected() const { return state_ == kDisconnected; }
void send(string&& message); // C++11
void send(const void* message, int len);
void send(const StringPiece& message);
// void send(Buffer&& message); // C++11
void send(Buffer* message); // this one will swap data
void shutdown(); // NOT thread safe, no simultaneous calling
void setContext(const boost::any& context)
{
context_ = context;
}
const boost::any& getContext() const
{
return context_;
}
boost::any* getMutableContext()
{
return &context_;
}
void setConnectionCallback(const ConnectionCallback& cb)
{
connectionCallback_ = cb;
}
void setMessageCallback(const MessageCallback& cb)
{
messageCallback_ = cb;
}
private:
enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };
EventLoop* loop_;
ConnectionCallback connectionCallback_;
MessageCallback messageCallback_;
WriteCompleteCallback writeCompleteCallback_;
boost::any context_;
};
TcpClient
相比较于TcpServer,TcpClient主要负责的就是客户端的连接操作
class TcpClient : noncopyable
{
public:
// TcpClient(EventLoop* loop);
// TcpClient(EventLoop* loop, const string& host, uint16_t port);
TcpClient(EventLoop* loop,
const InetAddress& serverAddr,
const string& nameArg);
~TcpClient(); // force out-line dtor, for std::unique_ptr members.
void connect();//
连接服务器
void disconnect();//
关闭连接
void stop();
//
获取客⼾端对应的通信连接
Connection
对象的接⼝,发起
connect
后,有可能还没有连接建⽴成
功
TcpConnectionPtr connection() const
{
MutexLockGuard lock(mutex_);
return connection_;
}
///
连接服务器成功时的回调函数
void setConnectionCallback(ConnectionCallback cb)
{
connectionCallback_ = std::move(cb);
}
///
收到服务器发送的消息时的回调函数
void setMessageCallback(MessageCallback cb)
{
messageCallback_ = std::move(cb);
}
private:
EventLoop* loop_;
ConnectionCallback connectionCallback_;
MessageCallback messageCallback_;
WriteCompleteCallback writeCompleteCallback_;
TcpConnectionPtr connection_ GUARDED_BY(mutex_);
};
class CountDownLatch : noncopyable
{
public:
explicit CountDownLatch(int count);
void wait() {
MutexLockGuard lock(mutex_);
while (count_ > 0)
{
condition_.wait();
}
}
void countDown() {
MutexLockGuard lock(mutex_); --count_;
if (count_ == 0)
{
condition_.notifyAll();
}
}
int getCount() const;
private:
mutable MutexLock mutex_;
Condition condition_ GUARDED_BY(mutex_);
int count_ GUARDED_BY(mutex_);
};
Buffer
在Buffer中最常用的方法就是string retrieveAllAsString(),这个方法就是取出当前IO就绪中的数据。
class Buffer : public muduo::copyable
{
public:
static const size_t kCheapPrepend = 8;
static const size_t kInitialSize = 1024;
explicit Buffer(size_t initialSize = kInitialSize)
: buffer_(kCheapPrepend + initialSize),
readerIndex_(kCheapPrepend),
writerIndex_(kCheapPrepend);
void swap(Buffer& rhs)
size_t readableBytes() const
size_t writableBytes() const
const char* peek() const
const char* findEOL() const
const char* findEOL(const char* start) const
void retrieve(size_t len)
void retrieveInt64()
void retrieveInt32()
void retrieveInt16() void retrieveInt8()
string retrieveAllAsString()
string retrieveAsString(size_t len)
void append(const StringPiece& str)
void append(const char* /*restrict*/ data, size_t len)
void append(const void* /*restrict*/ data, size_t len)
char* beginWrite()
const char* beginWrite() const
void hasWritten(size_t len)
void appendInt64(int64_t x)
void appendInt32(int32_t x)
void appendInt16(int16_t x)
void appendInt8(int8_t x)
int64_t readInt64()
int32_t readInt32()
int16_t readInt16()
int8_t readInt8()
int64_t peekInt64() const
int32_t peekInt32() const
int16_t peekInt16() const
int8_t peekInt8() const
void prependInt64(int64_t x)
void prependInt32(int32_t x)
void prependInt16(int16_t x)
void prependInt8(int8_t x)
void prepend(const void* /*restrict*/ data, size_t len)
private:
std::vector<char> buffer_;
size_t readerIndex_;
size_t writerIndex_;
static const char kCRLF[];
};
更多推荐
所有评论(0)