muduo : TcpServer
来源:互联网 发布:珠三角物流网络 编辑:程序博客网 时间:2024/05/17 22:25
引言
上篇博文学习了Acceptor
class 的实现,它仅仅是对Channel和Socket
的简单封装,对使用者来说简单易用。这得益于底层架构Reactor。接下来,开始学习muduo对于建立连接的处理。这属于muduo提到的三个半事件
中的第一个。可以想想一下,TcpServer
class应该也是对Acceptor
,Poller
的封装。
连接处理过程
首先TcpServer通过Acceptor向Poller注册了一个Channel,该Channel关注acceptSocket的readable事件,并设置了回调函数Acceptor::newConnectionCallback
为TcpServer::newConnection
然后,当有client连接时,Poller返回该Channel,接着调用该Channel::handleEvent–>handleRead。在Acceptor中accept
该连接,然后调用设置好的Acceptor::newConnectionCallback
,即TcpServer::newConnection
接着,对于每个连接,TcpServer会创建一个TcpConnnection来管理。BTW,TcpConnection是最为复杂的一个class,使用shared_ptr管理,因为它的生命周期比较模糊,这一点后面再分析。
最后,会调用TcpConnnection::connectEstablish
,它会回调用户设置好的回调函数connectionCallback。
(类与类之间通过回调函数联系在了一起)
成员变量
private: typedef std::map<string, TcpConnectionPtr> ConnectionMap; EventLoop* loop_; // the acceptor loop const string hostport_; // 端口号 const string name_; // 名字 boost::scoped_ptr<Acceptor> acceptor_; // avoid revealing Acceptor boost::scoped_ptr<EventLoopThreadPool> threadPool_; ConnectionCallback connectionCallback_; MessageCallback messageCallback_; WriteCompleteCallback writeCompleteCallback_; bool started_; // always in loop thread int nextConnId_; ConnectionMap connections_;
挑几个重点成员:
boost::scoped_ptr<Acceptor> acceptor_
; 这是上篇文章分析的用于接收连接的class,只在TcpServer内部使用,因此使用scoped_ptr管理EventLoop* loop_;
Reactor的关键classmap<string, TcpConnectionPtr> connections_
; 管理TcpConnection的容器,确切的讲应该是TcpServer通过shared_ptr管理TcpConnection(即TcpConnectionPtr),主要是因为TcpConnection拥有模糊的生命周期。muduo网络库的使用这也会使用TcpConnectionPtr作为参数。每个连接有一个唯一的名字,在创建时生成。
TcpServer::newConnection
void TcpServer::newConnection(int sockfd, const InetAddress& peerAddr){ // 这两句先不用关心 loop_->assertInLoopThread(); EventLoop* ioLoop = threadPool_->getNextLoop(); // 生成唯一的name char buf[32]; snprintf(buf, sizeof buf, ":%s#%d", hostport_.c_str(), nextConnId_); ++nextConnId_; string connName = name_ + buf; LOG_INFO << "TcpServer::newConnection [" << name_ << "] - new connection [" << connName << "] from " << peerAddr.toHostPort(); // 创建一个新的TcpConnection,使用shared_ptr管理 InetAddress localAddr(sockets::getLocalAddr(sockfd)); // FIXME poll with zero timeout to double confirm the new connection TcpConnectionPtr conn( new TcpConnection(ioLoop, connName, sockfd, localAddr, peerAddr)); // 将该TcpConnection加入到TcpServer的map容器中 connections_[connName] = conn; // 设置一些回调函数,将用户给TcpServer设置的回调传递给TcpConnection conn->setConnectionCallback(connectionCallback_); conn->setMessageCallback(messageCallback_); conn->setWriteCompleteCallback(writeCompleteCallback_); conn->setCloseCallback( boost::bind(&TcpServer::removeConnection, this, _1)); // 调用conn->connectEstablished() ioLoop->runInLoop(boost::bind(&TcpConnection::connectEstablished, conn));}
具体过程见注释,这就是三个半事件
中的第一个,比较简单。
使用示例
https://github.com/huntinux/muduo-learn/tree/v0.3
void onConnection(const muduo::net::TcpConnectionPtr& conn){ if(conn->connected()) { std::cout << "New connection" << std::endl; } else { std::cout << "Connection failed" << std::endl; }}void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer *buffer) //const char* data, //ssize_t len){ const std::string readbuf = buffer->retrieveAllAsString(); std::cout << "Receive :" << readbuf.size()<< " bytes." << std::endl << "Content:" << readbuf << std::endl; }int main(){ muduo::net::EventLoop loop; muduo::net::TcpServer server(&loop, "8090"); server.setConnectionCallback(onConnection); server.setMessageCallback(onMessage); server.start(); loop.loop();}
可以看到TcpServer使用比较方便,只需要设置好相应的回调函数,然后start()。
TcpServer在后台默默地做了很多事情:socket、bind、listen、epoll_wait、accept等等。
此外,示例代码是从muduo源码提取出来的,仅供参考。
- muduo : TcpServer
- muduo源码分析--TcpServer
- muduo TcpServer类
- muduo::Acceptor、TcpServer分析
- muduo源码分析之TcpServer
- muduo库的TcpServer和TcpConnection用法
- muduo源码分析之多线程TcpServer
- muduo网络库学习笔记(12):TcpServer和TcpConnection类
- muduo中的TcpServer一次完整的工作(上)
- muduo中的TcpServer一次完整的工作(下)
- muduo库的学习8---TcpServer与TcpClient的基本设计---TcpServer
- tcpServer
- TCPServer
- muduo源码分析--事件回调层次是怎么传递的Tcpserver Channel TcpConnection
- muduo源码分析--事件如何被关注的 EpollPoller Channel TcpServer
- muduo库阅读(40)——Net部分:TCP服务器TcpServer
- muduo库的学习7---TcpServer与TcpClient的基本设计---总论
- muduo库的学习10---TcpServer与TcpClient的基本设计---TcpConnection建立与关闭
- Spring中加载配置文件的方式
- resources中的color 设置
- 从零开始,DIY一个jQuery(1)
- Nginx模块如何调试
- 欢迎使用CSDN-markdown编辑器
- muduo : TcpServer
- Tomcat的8005、8009,8080端口解释
- 文件操作
- Oracle/SQL 修改字段类型和长度
- 100. Same Tree
- poj 1251
- 2629 Identity Card
- DrawerLayout禁用侧边滑动
- 【52】正则表达式匹配