欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++使用Muduo庫(kù)實(shí)現(xiàn)英譯漢功能

 更新時(shí)間:2025年05月06日 10:57:56   作者:_麥麥_  
Muduo庫(kù)是一個(gè)基于非阻塞IO和事件驅(qū)動(dòng)的C++高并發(fā)TCP網(wǎng)絡(luò)編程庫(kù),它是一款基于主從Reactor模型的網(wǎng)絡(luò)庫(kù),本文給大家介紹了C++如何使用Muduo庫(kù)實(shí)現(xiàn)英譯漢功能,需要的朋友可以參考下

一、前言

在本文將會(huì)為大家介紹Muduo庫(kù)常用的一些接口,并借助這些接口來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單版的英譯漢服務(wù)器和客戶(hù)端,希望能夠幫助大家加深對(duì)Muduo庫(kù)的使用?。。?!

二、正文

1.Muduo庫(kù)常見(jiàn)接口介紹

1.1 TcpServer類(lèi)基礎(chǔ)介紹

● TcpConnectionPtr

typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;

TcpConnectionPtr屬于TcpConnection類(lèi),但是我們?cè)诰帉?xiě)服務(wù)器的時(shí)候也需要接受客戶(hù)端的連接,當(dāng)連接到來(lái)的時(shí)候,由連接事件的回調(diào)函數(shù)來(lái)處理連接

● ConnectionCallback

 typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback;

ConnectionCallback是服務(wù)器處理連接事情的回調(diào)函數(shù),當(dāng)有來(lái)自客戶(hù)端的連接到來(lái)時(shí),就會(huì)自動(dòng)調(diào)用該函數(shù)來(lái)處理連接

● MessageCallback

 typedef std::function<void (const TcpConnectionPtr&, Buffer*,
 Timestamp)> MessageCallback;

 MessageCallback是服務(wù)器處理連接消息的回調(diào)函數(shù),當(dāng)客戶(hù)端傳來(lái)消息時(shí),就會(huì)自動(dòng)調(diào)用該函數(shù)來(lái)處理消息

● InetAddress 

 class InetAddress : public muduo::copyable
 {
 public:
     InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
 };

InetAddress 字段與服務(wù)器的設(shè)置有關(guān),該字段將ip,port與ipv6合并成為一個(gè)字段,當(dāng)我們?cè)O(shè)置服務(wù)器的時(shí)候就需要傳遞該字段,來(lái)指明服務(wù)器的ip地址,端口號(hào)和是否采取ipv6。

● TcpServer

 class TcpServer : noncopyable
 {
 public:
     enum Option
     {
         kNoReusePort,
         kReusePort,
     };
     
    TcpServer(EventLoop* loop,const InetAddress& listenAddr,const string&         
              nameArg,Option option = kNoReusePort);
 
    void setThreadNum(int numThreads);
    void start();
     
    /// 當(dāng)?個(gè)新連接建?成功的時(shí)候被調(diào)?
    void setConnectionCallback(const ConnectionCallback& cb { connectionCallback_ = cb; }
     
    ///消息的業(yè)務(wù)處理回調(diào)函數(shù)--這是收到新連接消息的時(shí)候被調(diào)?的函數(shù)
    void setMessageCallback (const MessageCallback& cb)
     { messageCallback_ = cb; }
 };

TcpServer類(lèi)則是我們等會(huì)字典服務(wù)器要使用的主體,在其構(gòu)造函數(shù)中我們要傳遞InetAddress字段,表明ip和端口號(hào);傳遞EventLoop指針來(lái)進(jìn)行事件監(jiān)控,Option選項(xiàng)則是指明服務(wù)器端口是否服用;start函數(shù)則是啟動(dòng)服務(wù)器;在啟動(dòng)服務(wù)器之前,我們還需要設(shè)置連接建立回調(diào)函數(shù)和消息處理的回調(diào)函數(shù)

1.2 EventLoop類(lèi)

 class EventLoop : noncopyable
 {
 public:
 /// Loops forever.
 /// Must be called in the same thread as creation of the object.
 void loop();
 /// Quits loop.
 /// This is not 100% thread safe, if you call through a raw pointer,
 /// better to call through shared_ptr<EventLoop> for 100% safety.
 void quit();
 TimerId runAt(Timestamp time, TimerCallback cb);
 /// Runs callback after @c delay seconds.
 /// Safe to call from other threads.
 TimerId runAfter(double delay, TimerCallback cb);
 /// Runs callback every @c interval seconds.
 /// Safe to call from other threads.
 TimerId runEvery(double interval, TimerCallback cb);
 /// Cancels the timer.
 /// Safe to call from other threads.
 void cancel(TimerId timerId);
 private:
 std::atomic<bool> quit_;
 std::unique_ptr<Poller> poller_;
 mutable MutexLock mutex_;
 std::vector<Functor> pendingFunctors_ GUARDED_BY(mutex_);
 };

EventLoop類(lèi)是幫助我們服務(wù)器進(jìn)行事件監(jiān)控的,一旦調(diào)用loop( )函數(shù)就會(huì)一直死循環(huán)進(jìn)入事件監(jiān)控的狀態(tài) 

1.3 TcpConnection類(lèi)

class TcpConnection : noncopyable,
 public std::enable_shared_from_this<TcpConnection>
 {
 public:
 /// Constructs a TcpConnection with a connected sockfd
 ///
 /// User should not create this object.
 TcpConnection(EventLoop* loop,
               const string& name,
               int sockfd,
               const InetAddress& localAddr,
               const InetAddress& peerAddr);
 bool connected() const { return state_ == kConnected; }
 bool disconnected() const { return state_ == kDisconnected; }
 void send(string&& message); // C++11
 void send(const void* message, int len);
 void send(const StringPiece& message);
 // void send(Buffer&& message); // C++11
 void send(Buffer* message);  // this one will swap data
 void shutdown(); // NOT thread safe, no simultaneous calling
 void setContext(const boost::any& context)
 { context_ = context; }
 const boost::any& getContext() const
 { return context_; }
 boost::any* getMutableContext()
 { return &context_; }
 void setConnectionCallback(const ConnectionCallback& cb)
 { connectionCallback_ = cb; }
 void setMessageCallback(const MessageCallback& cb)
 { messageCallback_ = cb; }
 private:
 enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };
 EventLoop* loop_;
 ConnectionCallback connectionCallback_;
 MessageCallback messageCallback_;
 WriteCompleteCallback writeCompleteCallback_;
 boost::any context_;
 };

在TcpConnection與連接相關(guān)的類(lèi)常用函數(shù)的有:

①判斷當(dāng)前的連接情況——connected() / disconnected()

②向連接的遠(yuǎn)端服務(wù)端發(fā)送消息——send()

1.4 TcpClient類(lèi)基礎(chǔ)介紹

● TcpClient

 TcpClient(EventLoop* loop,const InetAddress& serverAddr,
 const string& nameArg);

對(duì)于TcpClient的構(gòu)造需要傳遞loop指針進(jìn)行事件監(jiān)控,InetAddress來(lái)指明服務(wù)端的IP和port,nameArg則是指明TcpClient的命名

●void connect()

調(diào)用該函數(shù),TcpClient則會(huì)向已經(jīng)設(shè)置好的遠(yuǎn)端服務(wù)器進(jìn)行連接 

●void disconnect()

調(diào)用該函數(shù),TcpClient則會(huì)取消與遠(yuǎn)端服務(wù)器的連接

 ●void setConnectionCallback(ConnectionCallback cb)

/// 連接服務(wù)器成功時(shí)的回調(diào)函數(shù)
 
void setConnectionCallback(ConnectionCallback cb)
 { connectionCallback_ = std::move(cb); }

 ●void setMessageCallback(MessageCallback cb)

 /// 收到服務(wù)器發(fā)送的消息時(shí)的回調(diào)函數(shù)
 
void setMessageCallback(MessageCallback cb)
 { messageCallback_ = std::move(cb); }

1.5 CountDownLatch 類(lèi)

因?yàn)?muduo 庫(kù)不管是服務(wù)端還是客?端都是異步操作, 對(duì)于客?端來(lái)說(shuō)如果我們?cè)谶B接還沒(méi)有完全建?成功的時(shí)候發(fā)送數(shù)據(jù),這是不被允許的。 因此我們可以使?內(nèi)置的CountDownLatch 類(lèi)進(jìn)?同步控制。具體的思路就是給計(jì)數(shù)器count一個(gè)初值,比如說(shuō)1,當(dāng)連接建立成功的時(shí)候,我們將該值減少為0,才進(jìn)行l(wèi)oop的事件監(jiān)控,否則就一直處于阻塞等待連接的狀態(tài),避免client還沒(méi)有建立連接成功,就進(jìn)入事件的監(jiān)控,這是不符合邏輯的。

 class CountDownLatch : noncopyable
 {
 public:
     explicit CountDownLatch(int count);
     void wait(){
         MutexLockGuard lock(mutex_);
         while (count_ > 0)
         {
             condition_.wait();
         }
     }
 
     void countDown(){
         MutexLockGuard lock(mutex_);--count_;
         if (count_ == 0)
         {
             condition_.notifyAll();
         }
     }
     int getCount() const;
 private:
     mutable MutexLock mutex_;
     Condition condition_ GUARDED_BY(mutex_);
     int count_ GUARDED_BY(mutex_);
 };

1.6 Buffer類(lèi)基礎(chǔ)介紹

class Buffer : public muduo::copyable
 {
 public:
 static const size_t kCheapPrepend = 8;
 static const size_t kInitialSize = 1024;
 explicit Buffer(size_t initialSize = kInitialSize)
     : buffer_(kCheapPrepend + initialSize),
     readerIndex_(kCheapPrepend),
     writerIndex_(kCheapPrepend);
 void swap(Buffer& rhs)
 size_t readableBytes() const
 size_t writableBytes() const
 const char* peek() const
 const char* findEOL() const
 const char* findEOL(const char* start) const
 void retrieve(size_t len)
 void retrieveInt64()
 void retrieveInt32()
 void retrieveInt16()
 void retrieveInt8()
 string retrieveAllAsString()
 string retrieveAsString(size_t len)
 void append(const StringPiece& str)
 void append(const char* /*restrict*/ data, size_t len)
 void append(const void* /*restrict*/ data, size_t len)
 char* beginWrite()
 const char* beginWrite() const
 void hasWritten(size_t len)
 void appendInt64(int64_t x)
 void appendInt32(int32_t x)
 void appendInt16(int16_t x)
 void appendInt8(int8_t x)
 int64_t readInt64()
 int32_t readInt32()
 int16_t readInt16()
 int8_t readInt8()
 int64_t peekInt64() const
 int32_t peekInt32() const
 int16_t peekInt16() const
 int8_t peekInt8() const
 void prependInt64(int64_t x)
 void prependInt32(int32_t x)
 void prependInt16(int16_t x)
 void prependInt8(int8_t x)
 void prepend(const void* /*restrict*/ data, size_t len)
 private:
 std::vector<char> buffer_;
 size_t readerIndex_;
 size_t writerIndex_;
 static const char kCRLF[];
 };

在Buffer類(lèi)中,我們這次用到的接口是retrieveAllAsString(),由于我們字典翻譯的請(qǐng)求間隔時(shí)間比較長(zhǎng),因此默認(rèn)緩沖區(qū)里的數(shù)據(jù)就是一次完整的翻譯請(qǐng)求,所以我們就使用retrieveAllAsString()接口將緩沖區(qū)的數(shù)據(jù)全部讀作為一次完整的請(qǐng)求

 2. Muduo庫(kù)英譯漢服務(wù)

2.1 英譯漢TCP服務(wù)器

/*
    實(shí)現(xiàn)一個(gè)翻譯服務(wù)器,客戶(hù)端發(fā)送過(guò)來(lái)一個(gè)英語(yǔ)單詞,返回一個(gè)漢語(yǔ)詞語(yǔ)
*/
 
 
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/TcpConnection.h>
#include <muduo/net/TcpClient.h>
#include <muduo/net/Buffer.h>
#include <iostream>
#include <string>
#include <unordered_map>
 
 
class DicServer{
public:
    DicServer(int port)
        :_server(&_baseloop,
        muduo::net::InetAddress("0.0.0.0",port),
        "DicServer",muduo::net::TcpServer::Option::kReusePort)
    {
        //設(shè)置連接事件(連接建立/管理)的回調(diào)
        _server.setConnectionCallback(std::bind(&DicServer::onConnection,this,std::placeholders::_1));
        //設(shè)置連接消息的回調(diào)
        _server.setMessageCallback(std::bind(&DicServer::onMessage,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
 
    }
 
    void start()
    {
        _server.start();    //先開(kāi)始監(jiān)聽(tīng)
        _baseloop.loop();   //再開(kāi)始死循環(huán)事件監(jiān)控
    }
private:
    void onConnection(const muduo::net::TcpConnectionPtr &conn)
    {
        if(conn->connected())
            std::cout<<"連接建立!\n";
        else
            std::cout<<"連接斷開(kāi)!\n";
    }
 
    void onMessage(const muduo::net::TcpConnectionPtr &conn,muduo::net::Buffer *buf,muduo::Timestamp)
    {
        static std::unordered_map<std::string,std::string> dict_map={
            {"hello","你好"},
            {"world","世界"},
            {"worker","打工人"}
        };
        std::string msg=buf->retrieveAllAsString();
        std::string res;
        auto it=dict_map.find(msg);
        if(it != dict_map.end())
            res=it->second;
        else    
            res="未知單詞!";
        
        conn->send(res);
    }
 
public:
    muduo::net::EventLoop _baseloop;
    muduo::net::TcpServer _server;
 
};
 
int main()
{
    DicServer server(9090);
    server.start();
    return 0;
}

2.2 英譯漢客戶(hù)端

#include <muduo/net/TcpClient.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/EventLoopThread.h>
#include <muduo/net/TcpClient.h>
#include <muduo/net/Buffer.h>
#include <iostream>
#include <string>
 
 
class DictClient{
public:
    DictClient(const std::string &sip,int sport)
        :_baseloop(_loopthrad.startLoop())
        ,_downlatch(1) //初始化計(jì)數(shù)器為1,只有為0時(shí)才會(huì)喚醒
        ,_client(_baseloop,muduo::net::InetAddress(sip,sport),"DicClient")
    {
        //設(shè)置連接事件(連接建立/管理)的回調(diào)
        _client.setConnectionCallback(std::bind(&DictClient::onConnection,this,std::placeholders::_1));
        //設(shè)置連接消息的回調(diào)
        _client.setMessageCallback(std::bind(&DictClient::onMessage,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
        
        //連接服務(wù)器
        _client.connect();
        _downlatch.wait();
    }
 
    bool send(const std::string &msg)
    {
        if(_conn->connected() ==false)
        {
            std::cout<<"連接已經(jīng)斷開(kāi),發(fā)送數(shù)據(jù)失?。n";
            return false;
        }
        _conn->send(msg);
    }
private:
    void onConnection(const muduo::net::TcpConnectionPtr &conn)
    {
        if(conn->connected())
        {
            std::cout<<"連接建立!\n";
            _downlatch.countDown();//計(jì)數(shù)--,為0時(shí)喚醒阻塞
            _conn=conn;
        }
        else
        {
            std::cout<<"連接斷開(kāi)!\n";
            _conn.reset();
        }
    }
 
    void onMessage(const muduo::net::TcpConnectionPtr &conn,muduo::net::Buffer *buf,muduo::Timestamp)
    {
        std::string res = buf->retrieveAllAsString();
        std::cout<< res <<std::endl;
    }
 
 
private:
    muduo::net::TcpConnectionPtr _conn;
    muduo::CountDownLatch _downlatch;
    muduo::net::EventLoopThread _loopthrad;
    muduo::net::EventLoop *_baseloop;
    muduo::net::TcpClient _client;
 
};
 
 
int main()
{
    DictClient client("127.0.0.1",9090);
    while(1)
    {
        std::string msg;
        std::cin>>msg;
        client.send(msg);
    }
    return 0;
}

2.3 makefile文件

CFLAG= -std=c++11 -I ../../../../build/release-install-cpp11/include/
LFLAG= -L../../../../build/release-install-cpp11/lib  -lmuduo_net -lmuduo_base -pthread
 
all: server client
server: server.cpp
	g++  $(CFLAG) $^ -o $@ $(LFLAG)
client: client.cpp
	g++  $(CFLAG) $^ -o $@ $(LFLAG)

 CFLAG:處理文件中包含的頭文件

 LFLAG:指明鏈接的庫(kù)

 三、結(jié)語(yǔ)

以上就是C++使用Muduo庫(kù)實(shí)現(xiàn)英譯漢功能的詳細(xì)內(nèi)容,更多關(guān)于C++ Muduo英譯漢的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++中關(guān)鍵字const的詳細(xì)說(shuō)明和使用介紹(最全)

    C++中關(guān)鍵字const的詳細(xì)說(shuō)明和使用介紹(最全)

    const在C/C++中是十分重要的,如果單純理解為“常量”那么你的格局就小了,今天在這里給大家介紹一下const在C++中具體詳細(xì)的用法,需要的朋友可以參考下
    2025-03-03
  • C++實(shí)現(xiàn)教務(wù)管理系統(tǒng)

    C++實(shí)現(xiàn)教務(wù)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)教務(wù)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++使用GDAL庫(kù)實(shí)現(xiàn)Tiff文件的讀取

    C++使用GDAL庫(kù)實(shí)現(xiàn)Tiff文件的讀取

    這篇文章主要為大家詳細(xì)介紹了C++使用GDAL庫(kù)實(shí)現(xiàn)Tiff文件的讀取的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • C++模擬實(shí)現(xiàn)STL容器vector的示例代碼

    C++模擬實(shí)現(xiàn)STL容器vector的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器vector的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2022-11-11
  • C++實(shí)現(xiàn)五子棋游戲

    C++實(shí)現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 篩選法的C++實(shí)現(xiàn)

    篩選法的C++實(shí)現(xiàn)

    篩選法又稱(chēng)篩法,是求不超過(guò)自然數(shù)N(N>1)的所有質(zhì)數(shù)的一種方法。據(jù)說(shuō)是古希臘的埃拉托斯特尼(Eratosthenes,約公元前274~194年)發(fā)明的,又稱(chēng)埃拉托斯特尼篩子
    2013-10-10
  • 用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲

    用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 關(guān)于c++編譯protobuf時(shí)提示LNK2001 無(wú)法解析的外部符號(hào)的問(wèn)題

    關(guān)于c++編譯protobuf時(shí)提示LNK2001 無(wú)法解析的外部符號(hào)的問(wèn)題

    這篇文章主要介紹了關(guān)于c++編譯protobuf時(shí)提示LNK2001 無(wú)法解析的外部符號(hào)的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • OpenCV實(shí)現(xiàn)相機(jī)標(biāo)定板

    OpenCV實(shí)現(xiàn)相機(jī)標(biāo)定板

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)相機(jī)標(biāo)定板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C語(yǔ)言 詳解字符串基礎(chǔ)

    C語(yǔ)言 詳解字符串基礎(chǔ)

    在 C 語(yǔ)言中,字符串實(shí)際上是使用空字符 \0 結(jié)尾的一維字符數(shù)組。因此,\0 是用于標(biāo)記字符串的結(jié)束??兆址∟ull character)又稱(chēng)結(jié)束符,縮寫(xiě) NUL,是一個(gè)數(shù)值為 0 的控制字符,\0 是轉(zhuǎn)義字符,意思是告訴編譯器,這不是字符 0,而是空字符
    2022-04-04

最新評(píng)論