seo优化提升排名,东莞关键词优化效果,网上贸易平台有哪些,网站建设云尚网络简介
Acceptor类用于创建套接字#xff0c;设置套接字选项#xff0c;调用socket()-bind()-listen()-accept()函数#xff0c;接受连接#xff0c;然后调用TcpServer设置的connect事件的回调。
listen()//在TcpServer::start中调用
封装了一个listen fd相关…简介
Acceptor类用于创建套接字设置套接字选项调用socket()-bind()-listen()-accept()函数接受连接然后调用TcpServer设置的connect事件的回调。
listen()//在TcpServer::start中调用
封装了一个listen fd相关的操作,用于mainLoop
成员及属性解析
Acceptor - 逻辑上的内部类
接受器封装实质上就是对Channel的多一层封装
主要接口
listen
监听连接 当新连接进入时调用Socket::accept创建套接字触发TcpServer的回调
setNewConnectionCallback
TcpServer通过该接口设置回调当新连接套接字创建后创建TcpConnection对象
核心实现
通过socket::accept接受新连接获得套接字fd 这个fd作为参数调用TcpServer注册的回调
主要成员
loopchannelidlefd 非常巧妙的设计在服务器压力过大无法新建文件描述符时通过这个idlefd拒绝连接 来自libevent的设计
源码剖析
Acceptor.h
#ifndef MUDUO_NET_ACCEPTOR_H
#define MUDUO_NET_ACCEPTOR_H#include functional#include muduo/net/Channel.h
#include muduo/net/Socket.hnamespace muduo
{
namespace net
{
class EventLoop;
class InetAddress;///
/// Acceptor of incoming TCP connections.
///
class Acceptor : noncopyable
{public:typedef std::functionvoid (int sockfd, const InetAddress) NewConnectionCallback;Acceptor(EventLoop* loop, const InetAddress listenAddr, bool reuseport);~Acceptor();void setNewConnectionCallback(const NewConnectionCallback cb){ newConnectionCallback_ cb; }void listen();bool listening() const { return listening_; }// Deprecated, use the correct spelling one above.// Leave the wrong spelling here in case one needs to grep it for error messages.// bool listenning() const { return listening(); }private:void handleRead();EventLoop* loop_;Socket acceptSocket_;Channel acceptChannel_;NewConnectionCallback newConnectionCallback_;bool listening_;int idleFd_;
};} // namespace net
} // namespace muduo#endif // MUDUO_NET_ACCEPTOR_HAcceptor.cc
// Copyright 2010, Shuo Chen. All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)#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 errno.h
#include fcntl.h
//#include sys/types.h
//#include sys/stat.h
#include unistd.husing namespace muduo;
using namespace muduo::net;Acceptor::Acceptor(EventLoop* loop, const InetAddress listenAddr, bool reuseport): loop_(loop),acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),//创建一个非阻塞的socket fdacceptChannel_(loop, acceptSocket_.fd()),//创建socket fd的channellistening_(false),//是否处于监听状态idleFd_(::open(/dev/null, O_RDONLY | O_CLOEXEC))
{assert(idleFd_ 0);acceptSocket_.setReuseAddr(true); //设置ip地址复用acceptSocket_.setReusePort(reuseport); //设置端口复用acceptSocket_.bindAddress(listenAddr); //bind()函数封装,绑定ip和端口acceptChannel_.setReadCallback(std::bind(Acceptor::handleRead, this));//设置accept的回调函数
}Acceptor::~Acceptor()
{acceptChannel_.disableAll();//将mainloop poller监听集合中移除,取消所有事件的监听acceptChannel_.remove();//在events_删除channel::close(idleFd_);//关闭文件
}void Acceptor::listen()//开始监听fd
{loop_-assertInLoopThread();//判断是不是和创建时的io线程处于同一个线程listening_ true;//是否监听acceptSocket_.listen();//真正的监听函数acceptChannel_.enableReading();//设置监听读事件
}void Acceptor::handleRead()//当有client connnect时,则会调用
{loop_-assertInLoopThread();InetAddress peerAddr;//FIXME loop until no moreint connfd acceptSocket_.accept(peerAddr);//接收client connect,返回值accept()返回值if (connfd 0){// string hostport peerAddr.toIpPort();// LOG_TRACE Accepts of hostport;if (newConnectionCallback_)//如果设置了connect cb,则调用,否则则关闭这个连接{newConnectionCallback_(connfd, peerAddr);}else{sockets::close(connfd);}}else{LOG_SYSERR in Acceptor::handleRead;// Read the section named The special problem of// accept()ing when you cant in libevs doc.// By Marc Lehmann, author of libev.if (errno EMFILE){::close(idleFd_);idleFd_ ::accept(acceptSocket_.fd(), NULL, NULL);::close(idleFd_);idleFd_ ::open(/dev/null, O_RDONLY | O_CLOEXEC);}}
}