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();
}
执行结果如下:

网友评论