020網(wǎng)站設(shè)計(jì)互聯(lián)網(wǎng)營(yíng)銷培訓(xùn)班
一、muduo網(wǎng)絡(luò)庫(kù)主要提供了兩個(gè)類:
????????TcpServer:用于編寫服務(wù)器程序????????
????????TcpClient:用于編寫客戶端程序
二、三個(gè)重要的鏈接庫(kù):
????????libmuduo_net、libmuduo_base、libpthread
三、muduo庫(kù)底層就是epoll+線程池,其好處是:
????????可以將網(wǎng)絡(luò)I/O代碼和業(yè)務(wù)代碼區(qū)分開,用戶只需關(guān)注業(yè)務(wù),網(wǎng)絡(luò)的連接斷開、讀寫事件的上報(bào)與監(jiān)控交給muduo庫(kù)
四、muduo庫(kù)對(duì)外暴露兩個(gè)業(yè)務(wù)接口:
? ? ? ? 1.用戶的連接與斷開
? ? ? ? 2.用戶的可讀寫事件
五、基于muduo網(wǎng)絡(luò)庫(kù)的服務(wù)器開發(fā)步驟
????????1.組合TcpServer對(duì)象
????????2.創(chuàng)建Eventloop事件循環(huán)對(duì)象的指針
????????3.明確Tcpserver構(gòu)造函數(shù)需要什么參數(shù),輸出Chatserver的構(gòu)造函數(shù)
? ? ????????a.Tcpserver 主要提供兩個(gè)回調(diào)函數(shù):setConnectionCallback與setMessageCallback
? ? ????????b.在構(gòu)造函數(shù)中定義回調(diào)函數(shù),在類中定義具體回調(diào)的函數(shù)的實(shí)現(xiàn)
????????4.在當(dāng)前服務(wù)類的構(gòu)造函數(shù)中,注冊(cè)處理連接的回調(diào)函數(shù)和處理讀寫事件的回調(diào)函數(shù)
????????5.設(shè)置合適的服務(wù)端線程數(shù)量,muduo庫(kù)會(huì)自己分配I/O線程和work線程
/*
muduo網(wǎng)絡(luò)庫(kù)主要提供了兩個(gè)類:TcpServer:用于編寫服務(wù)器程序
TcpClient:用于編寫客戶端程序三個(gè)重要的鏈接庫(kù):
libmuduo_net、libmuduo_base、libpthreadmuduo庫(kù)底層就是epoll+線程池,其好處是:
可以將網(wǎng)絡(luò)I/O代碼和業(yè)務(wù)代碼區(qū)分開,用戶只需關(guān)注業(yè)務(wù),網(wǎng)絡(luò)的連接斷開、讀寫事件的上報(bào)與監(jiān)控交給muduo庫(kù)只暴露兩個(gè)業(yè)務(wù)接口:
1.用戶的連接與斷開
2.用戶的可讀寫事件*/
#include<muduo/net/TcpServer.h>
#include<muduo/net/EventLoop.h>
#include<functional>// #bind
#include<iostream>
#include<string>
using namespace std;
using namespace muduo;
using namespace muduo::net;
using namespace placeholders;/*
基于muduo網(wǎng)絡(luò)庫(kù)的服務(wù)器開發(fā)
1.組合TcpServer對(duì)象
2.創(chuàng)建Eventloop事件循環(huán)對(duì)象的指針
3.明確Tcpserver構(gòu)造函數(shù)需要什么參數(shù),輸出Chatserver的構(gòu)造函數(shù)a.Tcpserver 主要提供兩個(gè)回調(diào)函數(shù):setConnectionCallback與setMessageCallbackb.在構(gòu)造函數(shù)中定義回調(diào)函數(shù),在類中定義具體回調(diào)的函數(shù)的實(shí)現(xiàn)
4.在當(dāng)前服務(wù)類的構(gòu)造函數(shù)中,注冊(cè)處理連接的回調(diào)函數(shù)和處理讀寫事件的回調(diào)函數(shù)
5.設(shè)置合適的服務(wù)端線程數(shù)量,muduo庫(kù)會(huì)自己分配I/O線程和work線程*/
class ChatServer{
public://構(gòu)造函數(shù)對(duì)TcpServer進(jìn)行初始化,TcpServer沒有默認(rèn)構(gòu)造ChatServer(EventLoop *loop,//事件循環(huán) reactorconst InetAddress &listenAddr,//ip + portconst string &nameArg)// 線程/server的名稱: _server(loop, listenAddr, nameArg), _loop(loop){//給服務(wù)器注冊(cè)用戶連接與斷開的回調(diào)函數(shù),當(dāng)監(jiān)聽到連接/斷開時(shí)執(zhí)行onConnection,具體如何監(jiān)聽到是網(wǎng)絡(luò)庫(kù)的事情,無(wú)需用戶操心_server.setConnectionCallback(std::bind(&ChatServer::onConnection,this,_1));//相當(dāng)于this.onConnection(TcpConnectionPtr&)//給服務(wù)器注冊(cè)用戶讀寫事件的回調(diào)函數(shù)_server.setMessageCallback(std::bind(&ChatServer::onMessage,this,_1,_2,_3));//設(shè)置服務(wù)器端的線程數(shù)量,muduo庫(kù)會(huì)自適應(yīng)處理連接線程和工作線程的分配;CPU核數(shù)一般等于線程數(shù)//1個(gè)I/O線程,3個(gè)work線程_server.setThreadNum(4);}//開啟事件循環(huán)void start(){_server.start();}private://專門處理用戶的連接創(chuàng)建和斷開,相當(dāng)于epoll中監(jiān)聽到listenfd后執(zhí)行acceptvoid onConnection(const TcpConnectionPtr &conn){if(conn->connected()){cout<<conn->peerAddress().toIpPort()<<"->"<<conn->localAddress().toIpPort()<<"state: online"<<endl;}else{cout<<conn->peerAddress().toIpPort()<<"->"<<conn->localAddress().toIpPort()<<"state: offline"<<endl;conn->shutdown();//close(fd)}}//專門處理用戶的讀寫事件void onMessage(const TcpConnectionPtr &conn,//連接的共享指針Buffer *buffer,//緩沖區(qū),存放數(shù)據(jù)Timestamp time)//接收到數(shù)據(jù)的時(shí)間信息{//echo服務(wù)器string buf=buffer->retrieveAllAsString();cout<<"recv: "<<buf<<"time: "<<time.toString()<<endl;conn->send(buf);}TcpServer _server;// #1EventLoop *_loop;// #2 看作epoll};int main(){EventLoop loop;//類似于創(chuàng)建epollInetAddress addr("127.0.0.1",6000);//本地回環(huán)地址,服務(wù)器僅接受來(lái)自本機(jī)的連接。適合在開發(fā)階段進(jìn)行本地調(diào)試。ChatServer server(&loop,addr,"ChatServer");server.start();//epoll_ctl,listenfd加入epollloop.loop();//類似于epoll_wait,以阻塞的方式等待新用戶連接,已連接用戶的讀寫事件等return 0;
}
結(jié)果展示: