Muduo网络库源码分析之Acceptor和TcpServer

Acceptor

用于 accept 一个 TCP 连接,accept 接受成功后通知 TCP 连接的使用者。Acceptor 主要是供 TcpServer 使用的,其生命期由后者控制。一个 Acceptor 相当于持有服务端的一个 socket 描述符,该 socket 可以 accept 多个 TCP 客户连接,这个 accept 操作就是 Acceptor 实现的。

这里用到了一些封装好的 socket 和地址结构,如 class InetAddress 表示 sockaddr_in 的封装,如可以通过ip地址和port端口生成一个sockaddr_in; class Socket封装了部分关于socket套接字的操作,如Socket::bindAddress(InetAddress&) 将socket和一个sockaddr_in地址绑定,Socket::accept(InetAddress& peerAddr)将一个socket允许连接一个客户端地址peerAddr,Socket::listen()监听socket,Socket::shutdownWrite()实现关闭socket的写。这些类的封装可以看我这篇博客的分析。 Muduo网络库源码分析之对socket及其相关操作的封装

Acceptor在构造的时候会创建一个 socket 描述符 acceptSocket_(这是一个Socket类型即socket的RAII封装),并通过一个 Channel(注册事件及回调函数)管理 acceptSocket_::fd 成员(即socket描述符),一旦该 socket 可读即有TCP 客户连接请求,则 Channel::handleEvent() 将会调用 Acceptor::hanleRead() 执行 accept 接受一个TCP客户连接。Acceptor::handleRead() 还会将新的TCP客户连接和客户端地址通过回调函数 newConnectionCallback(connfd,peerAddr) 传给该TCP客户连接的使用者,通常是 TcpServer 类,这里的回调函数 newConnectionCallback 是在 Acceptor::setNewConnectionCallback(newConnectionCallback) 指定的,TcpServer 构造时 new 一个 Acceptor 后,会通过这个函数指定回调函数为 TcpServer::newConnection(int sockfd, const InetAddress& peerAddr)。值得注意的是这里又是统一事件源的思想,即通过 Channel 和 Poller 管理事件。Acceptor::listen() 的工作是:启动acceptSocket_::listen() 监听 socket 描述符,并通过 Channel::enableReading() 将socket 的可读事件注册到 Poller 的事件集合中。

Acceptor.h

#ifndef MUDUO_NET_ACCEPTOR_H
#define MUDUO_NET_ACCEPTOR_H

#include <boost/function.hpp>
#include <boost/noncopyable.hpp>

#include <muduo/net/Channel.h>
#include <muduo/net/Socket.h>

namespace muduo
{
namespace net
{

class EventLoop;
class InetAddress;

///
/// Acceptor of incoming TCP connections.
///
// accept一个TCP连接
class Acceptor : boost::noncopyable
{
 public:
     /* 新建立连接之后的回调 */
  typedef boost::function<void (int sockfd,
                                const InetAddress&)> NewConnectionCallback;

  Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport);
  ~Acceptor();

  /* 设置用户任务回调 */
  void setNewConnectionCallback(const NewConnectionCallback& cb)
  { newConnectionCallback_ = cb; }

  bool listenning() const { return listenning_; }
  void listen();            // 开始监听  

 private:
  void handleRead();        // listenfd -> Channel上的可读事件回调 

  EventLoop* loop_;         // 所在的 EventLoop
  Socket acceptSocket_;     // listenfd 
  Channel acceptChannel_;   // listenfd 对应的 Channel
  NewConnectionCallback newConnectionCallback_;     // 处理新连接的回调函数,accept 后调用
  bool listenning_;         // 是否正在 listen 
  int idleFd_;              //占位fd,用于fd满的情况
};

}
}

#endif  // MUDUO_NET_ACCEPTOR_H

Acceptor.cc

#include <muduo/net/Acceptor.h>

#include <muduo/base/Logging.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/SocketsOps.h>

#include <boost/bind.hpp>

#include <errno.h>
#include <fcntl.h>
//#include <sys/types.h>
//#include <sys/stat.h>
#include <unistd.h>

using namespace muduo;
using namespace muduo::net;

/* Acceptor 的数据成员包括Socket、Channel等,用于接受一个连接 */
Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, boo
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值