网络版汉译英服务(muduo)

文章目录

  • 网络版汉译英服务(muduo)
    • muduo库
      • muduo 库是什么
      • muduo 库常见接口介绍
        • muduo::net::EventLoop
        • muduo::net::TcpConnection
        • muduo::net::TcpServer
        • muduo::net::TcpClient
        • muduo::net::Buffer
    • 汉译英服务
      • 服务端
      • 客户端

网络版汉译英服务(muduo)

项目源码:汉译英服务

muduo库

muduo 库是什么

Muduo 由陈硕大佬开发,是一个基于非阻塞 IO事件驱动的 C++高并发 TCP 网络编程库。 它是一款基于主从 Reactor 模型的网络库,其使用的线程模型是 one loop per thread, 所谓 one loop per thread 指的是:

  • 一个线程只能有一个事件循环(EventLoop), 用于响应计时器和 IO 事件
  • 一个文件描述符只能由一个线程进行读写,换句话说就是一个 TCP 连接必须归属 于某个 EventLoop 管理

muduo 库常见接口介绍

muduo::net::EventLoop
class EventLoop : noncopyable 
{ public:  //开始永久事件循环void loop(); //停止循环void quit(); TimerId runAt(Timestamp time, TimerCallback cb); TimerId runAfter(double delay, TimerCallback cb); TimerId runEvery(double interval, TimerCallback cb); void cancel(TimerId timerId); private: std::atomic<bool> quit_; std::unique_ptr<Poller> poller_; mutable MutexLock mutex_; std::vector<Functor> pendingFunctors_ GUARDED_BY(mutex_); 
}; 
muduo::net::TcpConnection
class TcpConnection : noncopyable, 
public std::enable_shared_from_this<TcpConnection> 
{ public:  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_; 
}; 
muduo::net::TcpServer
typedef std::shared_ptr<TcpConnection> TcpConnectionPtr; 
typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback; 
typedef std::function<void (const TcpConnectionPtr&, Buffer*, Timestamp)> MessageCallback; class InetAddress : public muduo::copyable 
{ 
public: InetAddress(StringArg ip, uint16_t port, bool ipv6 = false); 
}; 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(); /// 当一个新连接建立成功的时候被调用 void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; } /// 消息的业务处理回调函数---这是收到新连接消息的时候被调用的函数 void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; } 
}; 
muduo::net::TcpClient
class TcpClient : noncopyable 
{ public: // TcpClient(EventLoop* loop); // TcpClient(EventLoop* loop, const string& host, uint16_t port); TcpClient(EventLoop* loop, const InetAddress& serverAddr, const string& nameArg); ~TcpClient(); // force out-line dtor, for std::unique_ptr members. //连接服务器void connect(); void disconnect();//关闭连接void stop(); //获取客户端对应的通信连接 Connection 对象的接口,发起 connect 后,有可能还没有连接建立成功 TcpConnectionPtr connection() const { MutexLockGuard lock(mutex_); return connection_; } /// 连接服务器成功时的回调函数 void setConnectionCallback(ConnectionCallback cb) { connectionCallback_ = std::move(cb); } /// 收到服务器发送的消息时的回调函数 void setMessageCallback(MessageCallback cb) { messageCallback_ = std::move(cb); } private: EventLoop* loop_; ConnectionCallback connectionCallback_; MessageCallback messageCallback_; WriteCompleteCallback writeCompleteCallback_; TcpConnectionPtr connection_ GUARDED_BY(mutex_); 
}; /* 
需要注意的是,因为 muduo 库不管是服务端还是客户端都是异步操作, 
对于客户端来说如果我们在连接还没有完全建立成功的时候发送数据,这是不被允
许的。 
因此我们可以使用内置的 CountDownLatch 类进行同步控制 
*/ 
class CountDownLatch : noncopyable 
{ public: explicit CountDownLatch(int count);//配合client的connect()函数使用,在连接还没有建立好时进行wait//直到client的连接回调函数被执行时,使用countDown()函数解除等待状态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_); 
}; 
muduo::net::Buffer
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 retrieve(size_t len) void retrieveInt64() void retrieveInt32() void retrieveInt16() void retrieveInt8() string retrieveAllAsString() string retrieveAsString(size_t len)  private: std::vector<char> buffer_; size_t readerIndex_; size_t writerIndex_; static const char kCRLF[]; 
};

汉译英服务

服务端

#include "include/muduo/net/TcpServer.h"
#include "include/muduo/net/TcpConnection.h"
#include "include/muduo/net/EventLoop.h"#include <iostream>
#include <functional>
#include <unordered_map>class TranslateServer
{public:TranslateServer(uint16_t port): _server(&_baseloop, muduo::net::InetAddress("0.0.0.0", port),"TranslateServer", muduo::net::TcpServer::kReusePort){// 将成员函数设置成server的回调函数_server.setConnectionCallback(std::bind(&TranslateServer::onConnection, this, std::placeholders::_1));_server.setMessageCallback(std::bind(&TranslateServer::onMessage, this, std::placeholders::_1,std::placeholders::_2, std::placeholders::_3));}void Start(){_server.start();_baseloop.loop(); }private:void onConnection(const muduo::net::TcpConnectionPtr &conn){// 建立新连接的回调函数if (conn->connected()){std::cout << "新连接建立成功!" << std::endl;}else{std::cout << "新连接退出" << std::endl;}}std::string translate(const std::string& req){static std::unordered_map<std::string,std::string> dictMap = {{"hello","你好"},{"Hello","你好"},{"吃了吗","肉夹馍"}};auto it = dictMap.find(req);if(it == dictMap.end())return "没找到";elsereturn it->second;}void onMessage(const muduo::net::TcpConnectionPtr &conn, muduo::net::Buffer *buffer, muduo::Timestamp){// 处理请求的回调函数//1.从buffer中拿到请求std::string req = buffer->retrieveAllAsString();//2.对请求进行处理std::string resp = translate(req);//3.发送响应conn->send(resp);}private:muduo::net::TcpServer _server;muduo::net::EventLoop _baseloop;
};int main()
{TranslateServer server(8088);server.Start();return 0;
}

客户端

#include "include/muduo/net/TcpServer.h"
#include "include/muduo/net/TcpClient.h"
#include "include/muduo/net/TcpConnection.h"
#include "include/muduo/base/CountDownLatch.h"
#include "include/muduo/net/EventLoopThread.h"#include <iostream>
#include <functional>class TranslateClient
{
public:TranslateClient(const std::string &server_ip, int server_port): _latch(1), _client(_loopthread.startLoop(), muduo::net::InetAddress(server_ip,server_port), "TranslateClient"){_client.setConnectionCallback(std::bind(&TranslateClient::onConnection, this, std::placeholders::_1));_client.setMessageCallback(std::bind(&TranslateClient::onMessage, this, std::placeholders::_1,std::placeholders::_2, std::placeholders::_3));}// 阻塞式等待连接成功void connect(){_client.connect();_latch.wait();}bool send(const std::string &msg){//连接状态正常再发送if(_conn->connected()){_conn->send(msg);return true;}return false;}private:// 建立连接成功后,唤醒上面的阻塞void onConnection(const muduo::net::TcpConnectionPtr &conn){if(conn->connected()){_latch.countDown();_conn = conn;}else{//连接关闭时的操作_conn.reset();}}void onMessage(const muduo::net::TcpConnectionPtr &conn, muduo::net::Buffer *buffer, muduo::Timestamp){std::cout<<"翻译结果:"<<buffer->retrieveAllAsString()<<std::endl;}muduo::CountDownLatch _latch;muduo::net::EventLoopThread _loopthread;muduo::net::TcpClient _client;muduo::net::TcpConnectionPtr _conn;   
};int main()
{TranslateClient client("127.0.0.1", 8088);client.connect();while (1){std::string msg;std::cin >> msg;client.send(msg);}return 0;
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/897297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在ArcMap中通过Python编写自定义工具(Python Toolbox)实现点转线工具

文章目录 一、需求二、实现过程2.1、创建Python工具箱&#xff08;.pyt&#xff09;2.2、使用catalog测试代码2.3、在ArcMap中使用工具 三、测试 一、需求 通过插件的形式将点转线功能嵌入ArcMap界面&#xff0c;如何从零开始创建一个插件&#xff0c;包括按钮的添加、工具的实…

C++之序列容器(vector,list,dueqe)

1.大体对比 在软件开发的漫长历程中&#xff0c;数据结构与算法始终占据着核心地位&#xff0c;犹如大厦的基石&#xff0c;稳固支撑着整个程序的运行。在众多编程语言中&#xff0c;数据的存储与管理方式各有千秋&#xff0c;而 C 凭借其丰富且强大的工具集脱颖而出&#xff…

【学习笔记】【DeepSeek AI 医生】2-2 AI家庭医生课程内容介绍

【DeepSeek AI 医生】2-4 项目详细分析及DeepSeek适用场景 一、Ollama部署二、可视化UI三、构建项目环境四、搭建项目架构五、Spring Al六、SSE服务端推送事件七、数据持久化八、线上部署 一、Ollama部署 Mac部署windows 部署ollama脚本、常用命令DeepSeek 提示词、角色、适用…

STM32 I2C驱动开发全解析:从理论到实战 | 零基础入门STM32第五十步

主题内容教学目的/扩展视频I2C总线电路原理&#xff0c;跳线设置&#xff0c;I2C协议分析。驱动程序与调用。熟悉I2C总线协议&#xff0c;熟练调用。 师从洋桃电子&#xff0c;杜洋老师 &#x1f4d1;文章目录 引言一、I2C驱动分层架构二、I2C总线驱动代码精析2.1 初始化配置&a…

Vercel Serverless

1. 引言 现代应用程序是为适应当前技术环境需求而设计的软件&#xff0c;采用现代开发工具和实践&#xff0c;针对云部署和可扩展性优化。它们由多个模块化小组件组成&#xff0c;便于集成和缩放&#xff0c;具有高度的敏捷性和适应性&#xff0c;能快速响应用户或业务需求变化…

国产操作系统之系统分区及分区的作用

国产操作系统之系统分区及分区的作用和挂载 Linux的系统分区跟Windows有着本质区别,在windows中大家知道c盘一般为系统盘,除c盘系统盘外,我们再分为D、E等文件存储盘,而在Linux中虽然是以文件目录著称的系统,但思路也一样的,比如针对系统分区中 /home、/var 和 /opt 等文…

字节码是由什么组成的?

Java字节码是Java程序编译后的中间产物&#xff0c;它是一种二进制格式的代码&#xff0c;可以在Java虚拟机&#xff08;JVM&#xff09;上运行。理解字节码的组成有助于我们更好地理解Java程序的运行机制。 1. Java字节码是什么&#xff1f; 定义 Java字节码是Java源代码经过…

微前端框架 Qiankun 的应用及问题分析

一、Qiankun 的核心应用场景与优势 多技术栈共存与灵活集成 Qiankun 支持主应用与子应用使用不同技术栈&#xff08;如 Vue、React、Angular 等&#xff09;&#xff0c;通过 HTML Entry 方式接入子应用&#xff0c;无需深度改造子应用即可实现集成&#xff0c;降低了技术迁移成…

function uuid_generate_v4()不存在(二)

说明&#xff1a;之前代码里用到了postgresql内嵌函数uid_generate_v4()生成记录的主键&#xff0c;提示该函数不存在&#xff0c;写了下面这篇博客记录了一下&#xff0c;今天又发现了新的问题&#xff0c;于是补充了这篇博客。 function uuid_generate_v4()不存在&#xff0…

6. 机器人实现远程遥控(具身智能机器人套件)

1. 启动控制脚本 远程作到 Raspberry Pi 中&#xff0c;并运行以下脚本&#xff1a; conda activate lerobotpython lerobot/scripts/control_robot.py \--robot.typelekiwi \--control.typeremote_robot登录笔记本电脑上&#xff0c;同时运行以下脚本&#xff1a; conda ac…

【简单的C++围棋游戏开发示例】

C围棋游戏开发简单示例&#xff08;控制台版&#xff09; ‌核心代码实现‌ #include <iostream> #include <vector> #include <queue> using namespace std;const int SIZE 9; // 简化棋盘为9x9‌:ml-citation{ref"1" data"citationList&…

RK3568平台(音频篇)audio_policy_volumes_drc.xml解析

audio_policy_volumes_drc.xml 是 Android 系统中用于配置音频策略和音量的 XML 文件。它定义了音频流的音量曲线、动态范围控制(DRC)参数以及音频设备的音量设置。该文件通常位于 /vendor/etc/ 或 /system/etc/ 目录下,是 Android 音频框架的重要组成部分。 以下是对 audi…

如何下载安装 PyCharm?

李升伟 整理 一、下载 PyCharm 访问官网 打开 PyCharm 官网&#xff0c;点击 "Download" 按钮25。 版本选择&#xff1a; 社区版&#xff08;Community&#xff09;&#xff1a;免费使用&#xff0c;适合个人学习和基础开发。 专业版&#xff08;Professional&#…

leetcode day27 455+376

455 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都有…

HPC超算系列2——新手指南1

一&#xff0c;平台简介&#xff1a; 主要是官方手册指南、B站视频&#xff08;培训视频、软件视频&#xff09; 1&#xff0c;超算平台架构&#xff1a; 和普通的家用电脑的架构不同&#xff0c; 主要区别在于&#xff1a;层次化的结构 &#xff08;1&#xff09;超算是有…

K8S单机部署

主线 :部署简单的单节点k8s - sowler - 博客园 学习网址&#xff1a;为什么我不能获取到镜像&#xff0c;ImagePullBackoff | Kuboard docker镜像源&#xff1a;https://chuxia.blog.csdn.net/article/details/145090710?spm1001.2101.3001.6650.3&utm_mediumdistribute…

web3区块链

Web3 是指下一代互联网&#xff0c;也被称为“去中心化互联网”或“区块链互联网”。它是基于区块链技术构建的&#xff0c;旨在创建一个更加开放、透明和用户主导的网络生态系统。以下是关于 Web3 的一些关键点&#xff1a; ### 1. **核心概念** - **去中心化**&#xff1…

SQL Server核心知识总结

SQL Server核心知识总结 &#x1f3af; 本文总结了SQL Server核心知识点,每个主题都提供实际可运行的示例代码。 一、SQL Server基础精要 1. 数据库核心操作 -- 1. 创建数据库&#xff08;核心配置&#xff09; CREATE DATABASE 学生管理系统 ON PRIMARY (NAME 学生管理系统…

android 支持自定义布局、线程安全、避免内存泄漏的 Toast 工具类

支持自定义布局&#xff1a;可以灵活地显示自定义样式的 Toast。 线程安全&#xff1a;确保在主线程中显示 Toast&#xff0c;避免崩溃。 避免内存泄漏&#xff1a;使用 ApplicationContext 和取消机制&#xff0c;防止内存泄漏问题。 工具类&#xff1a;作为一个通用的工具…

嵌入式人工智能应用-第6章 人脸检测

嵌入式人工智能应用 人脸检测 嵌入式人工智能应用1 人脸检测1.1 CNN 介绍1.2 人脸检测原理1.3 MTCNN介绍1.4 NCNN介绍2 系统安装2.1 安装依赖库NCNN2.2 运行对应的库3 总结1 人脸检测 1.1 CNN 介绍 卷积神经网络。卷积是什么意思呢?从数学上说,卷积是一种运算。它是我们学习…