日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

muduo之TcpServer

發布時間:2025/6/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 muduo之TcpServer 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ?TcpServer擁有Acceptor類,新連接到達時new TcpConnection后續客戶端和TcpConnection類交互。TcpServer管理連接和啟動線程池,用Acceptor接受連接。

// 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/TcpServer.h"#include "muduo/base/Logging.h" #include "muduo/net/Acceptor.h" #include "muduo/net/EventLoop.h" #include "muduo/net/EventLoopThreadPool.h" #include "muduo/net/SocketsOps.h"#include <stdio.h> // snprintfusing namespace muduo; using namespace muduo::net;TcpServer::TcpServer(EventLoop* loop,const InetAddress& listenAddr,const string& nameArg,Option option): loop_(CHECK_NOTNULL(loop)), //TcpServer所在的主線程下運行的事件驅動循環ipPort_(listenAddr.toIpPort()),/* 服務器負責監聽的本地ip和端口 */name_(nameArg),/* 服務器名字,創建時傳入 */acceptor_(new Acceptor(loop, listenAddr, option == kReusePort)),/* Acceptor對象,負責監聽客戶端連接請求,運行在主線程的EventLoop中 */threadPool_(new EventLoopThreadPool(loop, name_)),/* 事件驅動線程池,池中每個線程運行一個EventLoop */connectionCallback_(defaultConnectionCallback),/* 用戶傳入,有tcp連接到達或tcp連接關閉時調用,傳給TcpConnection */messageCallback_(defaultMessageCallback),/* 用戶傳入,對端發來消息時調用,傳給TcpConnection */nextConnId_(1) /* TcpConnection特有id,每增加一個TcpConnection,nextConnId_加一 */ { /* * 設置回調函數,當有客戶端請求時,Acceptor接收客戶端請求,然后調用這里設置的回調函數* 回調函數用于創建TcpConnection連接*/acceptor_->setNewConnectionCallback(std::bind(&TcpServer::newConnection, this, _1, _2)); }TcpServer::~TcpServer() {loop_->assertInLoopThread();LOG_TRACE << "TcpServer::~TcpServer [" << name_ << "] destructing";for (auto& item : connections_){TcpConnectionPtr conn(item.second);item.second.reset();conn->getLoop()->runInLoop(std::bind(&TcpConnection::connectDestroyed, conn));} }void TcpServer::setThreadNum(int numThreads) {assert(0 <= numThreads);threadPool_->setThreadNum(numThreads); }void TcpServer::start() {if (started_.getAndSet(1) == 0){threadPool_->start(threadInitCallback_);//啟動線程池,threadInitCallback_創建好所有線程后調用的回調函數assert(!acceptor_->listenning());loop_->runInLoop( //直接調用linsten函數std::bind(&Acceptor::listen, get_pointer(acceptor_)));} }/* * Acceptor接收客戶端請求后調用的回調函數* @param sockfd: 已經接收完成(三次握手完成)后的客戶端套接字* @param peerAddr: 客戶端地址* * Acceptor只負責接收客戶端請求* TcpServer需要生成一個TcpConnection用于管理tcp連接* * 1.TcpServer內有一個EventLoopThreadPool,即事件循環線程池,池子中每個線程都是一個EventLoop* 2.每個EventLoop包含一個Poller用于監聽注冊到這個EventLoop上的所有Channel* 3.當建立起一個新的TcpConnection時,這個連接會放到線程池中的某個EventLoop中* 4.TcpServer中的baseLoop只用來檢測客戶端的連接* * 從libevent的角度看就是* 1.EventLoopThreadPool是一個struct event_base的池子,池子中全是struct event_base* 2.TcpServer獨占一個event_base,這個event_base不在池子中* 3.TcpConnection會扔到這個池子中的某個event_base中*/ void TcpServer::newConnection(int sockfd, const InetAddress& peerAddr) {loop_->assertInLoopThread();EventLoop* ioLoop = threadPool_->getNextLoop();//從事件驅動線程池中取出一個線程給TcpConnection /* 為TcpConnection生成獨一無二的名字 */char buf[64];snprintf(buf, sizeof buf, "-%s#%d", ipPort_.c_str(), nextConnId_);++nextConnId_;string connName = name_ + buf;LOG_INFO << "TcpServer::newConnection [" << name_<< "] - new connection [" << connName<< "] from " << peerAddr.toIpPort();/* * 根據sockfd獲取tcp連接在本地的<地址,端口>* getsockname(int fd, struct sockaddr*, int *size);*/InetAddress localAddr(sockets::getLocalAddr(sockfd));// FIXME poll with zero timeout to double confirm the new connection// FIXME use make_shared if necessary/* 創建一個新的TcpConnection代表一個Tcp連接 */TcpConnectionPtr conn(new TcpConnection(ioLoop,connName,sockfd,localAddr,peerAddr));/* 添加到所有tcp 連接的map中,鍵是tcp連接獨特的名字(服務器名+客戶端<地址,端口>) */connections_[connName] = conn;/* 為tcp連接設置回調函數(由用戶提供) */conn->setConnectionCallback(connectionCallback_);conn->setMessageCallback(messageCallback_);conn->setWriteCompleteCallback(writeCompleteCallback_);/* * 關閉回調函數,由TcpServer設置,作用是將這個關閉的TcpConnection從map中刪除* 當poll返回后,發現被激活的原因是EPOLLHUP,此時需要關閉tcp連接* 調用Channel的CloseCallback,進而調用TcpConnection的handleClose,進而調用removeConnection*/conn->setCloseCallback(std::bind(&TcpServer::removeConnection, this, _1)); // FIXME: unsafe/* * 連接建立后,調用TcpConnection連接建立成功的函數* 1.新建的TcpConnection所在事件循環是在事件循環線程池中的某個線程* 2.所以TcpConnection也就屬于它所在的事件驅動循環所在的那個線程* 3.調用TcpConnection的函數時也就應該在自己所在線程調用* 4.所以需要調用runInLoop在自己的那個事件驅動循環所在線程調用這個函數* 5.當前線程是TcpServer的主線程,不是TcpConnection的線程,如果在這個線程直接調用會阻塞監聽客戶端請求* 6.其實這里不是因為線程不安全,即使在這個線程調用也不會出現線程不安全,因為TcpConnection本就是由這個線程創建的*/ioLoop->runInLoop(std::bind(&TcpConnection::connectEstablished, conn)); }void TcpServer::removeConnection(const TcpConnectionPtr& conn) {// FIXME: unsafeloop_->runInLoop(std::bind(&TcpServer::removeConnectionInLoop, this, conn)); }void TcpServer::removeConnectionInLoop(const TcpConnectionPtr& conn) {//關閉連接,把fd從epoll中del掉,要釋放connector(包括描述符)和channelloop_->assertInLoopThread();LOG_INFO << "TcpServer::removeConnectionInLoop [" << name_<< "] - connection " << conn->name();size_t n = connections_.erase(conn->name());(void)n;assert(n == 1);EventLoop* ioLoop = conn->getLoop();ioLoop->queueInLoop(std::bind(&TcpConnection::connectDestroyed, conn)); }

? ? ? ? 不多說

總結

以上是生活随笔為你收集整理的muduo之TcpServer的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲精品资源在线 | 欧美一区二区免费视频 | 国产91热爆ts人妖系列 | 日本精品一区二区三区四区的功能 | 欧美精品一区二区三区在线播放 | 成人在线精品视频 | 日韩在线三级 | 欧美老司机| 欧美一级生活片 | 欧美xx视频 | 波多野结衣女同 | 欧美一区视频 | 中文字幕在线观看第二页 | av性天堂网 | 欧美三级少妇高潮 | 日韩精品色哟哟 | 免费观看的av | 大j8黑人w巨大888a片 | 欧美日韩精品在线观看 | 亚洲成人网在线 | 蜜桃视频导航 | 日本加勒比中文字幕 | 亚洲资源网 | 欧美乱妇视频 | 三度诱惑免费版电影在线观看 | 99热| 欧美成人精品欧美一级私黄 | 免费午夜av | 蜜臀av性久久久久蜜臀aⅴ流畅 | 国产一区二区视频在线播放 | 欧亚成人av | 国产swag在线观看 | 狠狠撸视频 | 成人h动漫精品一区二区器材 | 日韩一区二区毛片 | 免费看国产片在线观看 | 欧美精选一区二区 | 黄色操人 | 女同性做爰三级 | 制服丝袜先锋影音 | 99亚洲视频 | 午夜不卡久久精品无码免费 | 中文字幕 人妻熟女 | 国产精品成人aaaa在线 | 日韩美女视频一区二区 | 痴女扩张宫交脱垂重口小说 | 欧美怡红院视频一区二区三区 | 久久久久麻豆 | 91女神在线| 成人77777| 欧美精品99久久 | 粉嫩av| 免费看欧美黑人毛片 | 美国免费高清电影在线观看 | 国产精品白嫩白嫩大学美女 | 国产初高中真实精品视频 | 四虎国产精品永久免费观看视频 | 污导航在线 | 午夜亚洲av永久无码精品 | 偷拍第1页 | 欧美撒尿777hd撒尿 | 精品久久视频 | 国产一区二区三区电影在线观看 | 夜色综合网 | 久久亚洲aⅴ无码精品 | 美女扒开尿口让男人桶 | 色婷婷av一区二区三区四区 | 日本久久久久 | 亚洲高清一区二区三区 | 国产精品乱码妇女bbbb | 成人做爰69片免费看 | 免费看成年人视频 | 国产www | 女人性做爰69片免费看 | 国产成人在线免费视频 | 豆花免费跳转入口官网 | 久久国产视频网 | 在线二区 | 国产精品视频在线看 | 黄色资源在线观看 | 1024精品一区二区三区日韩 | 国产免费午夜 | 香蕉狠狠爱视频 | av黄色国产 | 在线免费福利视频 | 91热爆在线 | 日韩精品在线免费看 | 国产精品无码av在线有声小说 | 黄色wwwww | 日本美女黄网站 | 色妹子综合| 色女人av | aa一级视频 | 青青草视频国产 | 欧美黄色大片免费看 | 亚洲性生活视频 | av在线激情 | 播播成人网 | 色播综合网 |