Muduo库设计(4)——Acceptor类

2019-11-28  本文已影响0人  Magic11

Acceptor类用于监听某个固定的端口,并不断地监测该端口是否有新的连接到来
Acceptor类在创建的同时会创建一个socket,并将该socket绑定到需要监听的端口号上,然后创建一个channel负责管理该socket对应的fd

Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr)
  : loop_(loop),
    acceptSocket_(sockets::createNonblockingOrDie()),    //创建socket
    acceptChannel_(loop, acceptSocket_.fd()),            //创建Channel
    listenning_(false)
{
  acceptSocket_.setReuseAddr(true);         //设置端口号可以重用,避免软件重启,端口号还被占用
  acceptSocket_.bindAddress(listenAddr);    //socket绑定到端口号
  acceptChannel_.setReadCallback(std::bind(&Acceptor::handleRead, this));
}

Acceptor开始监听该channel上是否有可读事件(有可读事件表明有新的连接到来)

void Acceptor::listen()
{
  loop_->assertInLoopThread();
  listenning_ = true;
  acceptSocket_.listen();
  acceptChannel_.enableReading();   //开始监测是否有可读事件(是否有新的连接)
}

当有新的连接到来时,调用accept接口来获取新连接对应的fd及对端的ip地址和端口号

void Acceptor::handleRead()
{
  loop_->assertInLoopThread();
  InetAddress peerAddr(0);
  int connfd = acceptSocket_.accept(&peerAddr);   //接受新的连接
  if (connfd >= 0) {
    if (newConnectionCallback_) {
      newConnectionCallback_(connfd, peerAddr);
    } else {
      sockets::close(connfd);
    }
  }
}

调用Acceptor的示例代码如下:

void newConnection(int sockfd, const muduo::InetAddress& peerAddr)
{
  printf("accepted a new connection from %s\n", peerAddr.toHostPort().c_str());
  ::write(sockfd, "How are you?\n", 13);
  sockets::close(sockfd);
}

int main()
{
  InetAddress listenAddr(9981);
  EventLoop loop;

  Acceptor acceptor(&loop, listenAddr);
  acceptor.setNewConnectionCallback(newConnection);
  
  acceptor.listen();

  loop.loop();
}

执行结果如下:


image.png
上一篇下一篇

猜你喜欢

热点阅读