zlm源码分析 - 网络

TcpServer

创建

TcpServer::TcpServer(const EventPoller::Ptr &poller) : Server(poller) {
    setOnCreateSocket(nullptr);
}

Server::Server(EventPoller::Ptr poller) {
    _poller = poller ? std::move(poller) : EventPollerPool::Instance().getPoller();
}

TcpServer::setOnCreateSocket
  _on_create_socket = [](const EventPoller::Ptr &poller) {
      return Socket::createSocket(poller, false);
    };
启动

创建监听套接字,并设置相关事件回调。

template<typename SessionType>
void start(uint16_t port, const std::string &host = "::", uint32_t backlog = 1024) {
  _session_alloc = [](const TcpServer::Ptr &server, const Socket::Ptr &sock) {
    auto session = std::make_shared<SessionType>(sock);
    session->setOnCreateSocket(server->_on_create_socket);
    return std::make_shared<SessionHelper>(server, session);
  };
  start_l(port, host, backlog);
}


TcpServer::start_l
  _socket = createSocket(_poller); // Socket::createSocket(true)
  _socket->setOnBeforeAccept(TcpServer::onBeforeAcceptConnection)
  _socket->setOnAccept([weak_self](Socket::Ptr &sock, shared_ptr<void> &complete) {
    auto ptr = sock->getPoller().get();
    auto server = strong_self->getServer(ptr);
    ptr->async([server, sock, complete]() {
      server->onAcceptConnection(sock);
    });
  });
  _socket->listen(port, host.c_str(), backlog);
  // 在每个线程都创建一个该服务器的副本
  EventPollerPool::Instance().for_each([&](const TaskExecutor::Ptr &executor) {
    EventPoller::Ptr poller = dynamic_pointer_cast<EventPoller>(executor);
    if (poller == _poller || !poller)
      return;
    auto &serverRef = _cloned_server[poller.get()];
    if (!serverRef)
      serverRef = onCreatServer(poller);
    if (serverRef)
      serverRef->cloneFrom(*this);
  });
  
  
Socket::Ptr Socket::createSocket(const EventPoller::Ptr &poller, bool enable_mutex){
    return std::make_shared<Socket>(poller, enable_mutex);
}


bool Socket::listen(uint16_t port, const string &local_ip, int backlog) {
    int sock = SockUtil::listen(port, local_ip.data(), backlog);
    return listen(makeSock(sock, SockNum::Sock_TCP));
}


int SockUtil::listen(const uint16_t port, const char *local_ip, int back_log)
  fd = (int)socket(family, SOCK_STREAM, IPPROTO_TCP);
  setReuseable(fd, true, false);
  setNoBlocked(fd);
  setCloExec(fd);
  bind_sock(fd, local_ip, port, family);
  ::listen(fd, back_log)
  return fd;
  

bool Socket::listen(const SockFD::Ptr &sock)
  closeSock();
  weak_ptr<SockFD> weak_sock = sock;
  weak_ptr<Socket> weak_self = shared_from_this();
  _enable_recv = true;
  _poller->addEvent(sock->rawFd(), EventPoller::Event_Read | EventPoller::Event_Error,
                    [weak_self, weak_sock](int event) {
      strong_self->onAccept(strong_sock, event);                    
    }); 
  _sock_fd = sock;
新连接
int Socket::onAccept(const SockFD::Ptr &sock, int event)
  if (event & EventPoller::Event_Read)
    int fd = (int)accept(sock->rawFd(), nullptr, nullptr);
    SockUtil::setNoSigpipe(fd);
    SockUtil::setNoBlocked(fd);
    SockUtil::setNoDelay(fd);
    SockUtil::setSendBuf(fd);
    SockUtil::setRecvBuf(fd);
    SockUtil::setCloseWait(fd);
    SockUtil::setCloExec(fd);
    
    // 为新连接的客户端socket,创建Socket和SockFD两个管理对象。
    Socket::Ptr peer_sock = _on_before_accept(_poller); // Socket::createSocket(false)
    auto peer_sock_fd = peer_sock->setPeerSock(fd);
    // 此处通过设置completed这个共享指针变量的销毁函数,来达到先执行_on_accept,再attachEvent的目的。
    shared_ptr<void> completed(nullptr, [peer_sock, peer_sock_fd](void *) {
      peer_sock->attachEvent(peer_sock_fd)    
    });
    _on_accept(peer_sock, completed);
    

TcpServer::onAcceptConnection(const Socket::Ptr &sock)
  auto helper = _session_alloc(std::dynamic_pointer_cast<TcpServer>(shared_from_this()), sock);
  auto session = helper->session();
  weak_ptr<Session> weak_session = session;
  sock->setOnRead([weak_session](const Buffer::Ptr &buf, struct sockaddr *, int) {
    strong_session->onRecv(buf);
  });
新连接数据流程

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值