Linux與UDP應用1:翻譯軟件

UDP應用1:翻譯軟件

本篇介紹

本篇基于UDP編程接口基本使用中封裝的服務器和客戶端進行改寫,基本功能如下:

  1. 從配置文件dict.txt讀取到所有的單詞和意思
  2. 客戶端向服務端發送英文
  3. 服務端向客戶端發送英文對應的中文意思

配置文件內容

下面的內容是本次實現使用的配置文件

apple: 蘋果
banana: 香蕉
cat: 貓
dog: 狗
book: 書
pen: 筆
happy: 快樂的
sad: 悲傷的
run: 跑
jump: 跳
teacher: 老師
student: 學生
car: 汽車
bus: 公交車
love: 愛
hate: 恨
hello: 你好
goodbye: 再見
summer: 夏天
winter: 冬天

設計翻譯軟件

根據上面對功能描述,下面對功能實現進行具體分析

設計字典類

既然是字典類,那么對應的就需要一個便于查詢的結構,本次以哈希表為例

因為服務端主要是接收客戶端的數據,所以服務端本身不直接處理翻譯功能,而是交給一個函數進行處理,但是如果這個函數直接裸露在外部就會導致字典本身和翻譯函數分開,所以本次考慮將翻譯函數作為字典類的成員函數

需要注意,本次默認使用的配置文件中英文單詞和中文意思使用的是一個冒號和空格進行分割,即: ,可以考慮讓用戶自己提供配置文件和分割符,所以類基本結構如下:

// 默認配置文件位置和配置文件
const std::string default_path = "./";
const std::string default_file = "dict.txt";// 默認分隔符
const std::string default_sep = ": ";class Dictionary
{
public:Dictionary(const std::string &path = default_path, const std::string &file = default_file, const std::string &sep = default_sep): _path(path), _file(file), _sep(sep){// 1. 讀取配置文件// 2. 分割字符串并將key和value添加到哈希表}// 翻譯std::string translate(const std::string &word){}~Dictionary(){}private:std::unordered_map<std::string, std::string> _dict; // 字典哈希表std::string _path;                                  // 配置文件路徑std::string _file;                                  // 配置文件std::string _sep;                                   // 分隔符
};

讀取配置文件并分割

首先是讀取配置文件,本次考慮將從配置文件中讀取到的字符串通過分割成keyvalue依次存入到一個哈希表中。并且因為是字典類,所以考慮在創建字典類對象時就完成前面的讀取和存儲操作

根據上面的思路需要考慮兩個步驟:

  1. 獲取并讀取配置文件
  2. 分割字符串獲取到keyvalue存儲到哈希表

讀取配置文件的操作就是打開指定的文件并讀取其中的內容,在本次配置文件的內容中,一行為一組數據,所以在讀取文件內容時需要按照行讀取

讀到一行數據后,需要將該行數據按照指定的分隔符進行切割存入keyvalue中,這里有兩種思路:

  1. 自行實現分割邏輯
  2. 使用庫函數

本次考慮使用第一種思路,那么對于分割邏輯來說,基本思路如下:

  1. 找到:第一次出現的位置,以該位置為終點,以字符串第一個字符為起點,切出第一個子串作為key
  2. 找到分隔符的下一個字符,以該位置為起點,以字符串結尾為終點,切出第二個子串作為value

將獲取到的keyvalue存入到哈希表中

重復上面的步驟直到讀取完畢文件,將文件關閉,代碼如下:

// 1. 讀取配置文件
std::string dictPath = default_path + default_file;
// 1.1 打開文件
std::fstream out(dictPath);// 2. 分割字符串并將key和value添加到哈希表
std::string message;
while (std::getline(out, message))
{// 分割字符串auto word_end = message.find(_sep, 0);std::string key = message.substr(0, word_end);std::string value = message.substr(word_end + sep.size(), message.size());// 存儲到哈希表中_dict.insert({key, value});
}out.close();

翻譯函數

所謂翻譯就是在哈希表中根據指定字符串查找對應的value并返回,基本代碼如下:

// 翻譯
std::string translate(const std::string &word)
{auto pos = _dict.find(word);if (pos == _dict.end())return "無指定單詞對應的中文意思";return pos->second;
}

修改服務端類

本次服務端做的任務就是接收客戶端發送的數據,再調用字典類的翻譯函數將翻譯結果返回給客戶端,所以實際上需要修改的就是兩點:

  1. 服務端需要拿到翻譯函數
  2. 執行翻譯功能并返回結果給客戶端

首先修改第一點,因為服務端本身沒有翻譯函數,所以需要外界傳遞,此時可以考慮在構造服務端時要求外部傳遞翻譯函數,對應地服務端就需要一個成員用于接收這個函數:

using task_t = std::function<std::string(const std::string &)>;class UdpServer
{
public:UdpServer(task_t t, uint16_t port = default_port): // ...,_translate(t){// ...}// ...
private:// ...task_t _translate; // 翻譯函數
};

需要注意,在構造函數中,沒有默認參數的形式參數一定要寫在有默認參數的形式參數之前,具體原因見C++中的缺省參數
接著修改第二點,執行翻譯函數并將結果返回給客戶端,這一步主要涉及到服務端的任務部分。在上一節中,主要任務是將客戶端發送的信息再發給客戶端,這次就是調用翻譯函數再將結果返回給客戶端,所以代碼如下:

// 啟動服務器
void start()
{if (!_isRunning){_isRunning = true;while (true){// 1. 接收客戶端信息// ...if (ret > 0){// ...// 翻譯std::string ret = _translate(buffer);ssize_t n = sendto(_socketfd, ret.c_str(), ret.size(), 0, &temp, temp.getLength());// ...}}}
}

修改服務端主函數

主要修改的地方就是創建服務端對象部分,因為需要傳遞一個翻譯任務函數,所以需要先創建一個字典類對象,再調用字典類對象中的翻譯方法,需要注意的是,不能直接將字典類的翻譯函數作為參數傳遞給服務端對象的構造函數,因為該函數的參數列表除了需要顯示傳遞的字符串對象外,還存在一個字典類對象,這并不符合服務端類構造函數要求的函數類型,這里提供兩個方法:

  1. 使用綁定,將字典類對象作為固定參數綁定給翻譯函數
  2. 使用lambda表達式,在表達式中調用翻譯函數

即:

=== “綁定”

// 創建字典類對象
std::shared_ptr<Dictionary> dict;
// 創建UdpServerModule對象
std::shared_ptr<UdpServer> udp_server = = std::make_shared<UdpServer>(std::bind(&Dictionary::translate, dict.get(), std::placeholders::_1));

=== “lambda表達式”

// 創建字典類對象
std::shared_ptr<Dictionary> dict;
// 創建UdpServerModule對象
std::shared_ptr<UdpServer> udp_server = = std::make_shared<UdpServer>([&dict](const std::string word){ dict->translate(word); 
});

測試

以綁定為例,服務端整體代碼如下:

#include "udp_server.hpp"
#include "dictionary.hpp"
#include <memory>using namespace UdpServerModule;
using namespace DictionaryModule;int main(int argc, char *argv[])
{// 創建字典類對象std::shared_ptr<Dictionary> dict;// 創建UdpServerModule對象std::shared_ptr<UdpServer> udp_server;if (argc == 1){// 綁定udp_server = std::make_shared<UdpServer>(std::bind(&Dictionary::translate, dict.get(), std::placeholders::_1));}else if (argc == 2){// std::string ip = argv[1]; 去除uint16_t port = std::stoi(argv[1]);udp_server = std::make_shared<UdpServer>(std::bind(&Dictionary::translate, dict.get(), std::placeholders::_1), port);}else{LOG(LogLevel::ERROR) << "錯誤使用,正確使用:" << argv[0] << " 端口(或者不寫)";exit(4);}udp_server->start();return 0;
}

客戶端代碼保持和上一節一樣,此處不再展示,運行結果如下:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72193.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72193.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72193.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Jeecg-Boot 開放接口開發實戰:在 Jeecg-Boot 的jeecg-system-biz中添加一個controller 實現免鑒權數據接口

Jeecg-Boot 開放接口開發實戰&#xff1a;在 Jeecg-Boot 的jeecg-system-biz中添加一個controller 實現免鑒權數據接口 一、場景需求分析 在微服務架構中&#xff0c;常需要快速實現以下兩類接口&#xff1a; 開放接口&#xff1a;無需登錄即可訪問&#xff08;如數據查詢、…

C++ ++++++++++

初始C 注釋 變量 常量 關鍵字 標識符命名規則 數據類型 C規定在創建一個變量或者常量時&#xff0c;必須要指定出相應的數據類型&#xff0c;否則無法給變量分配內存 整型 sizeof關鍵字 浮點型&#xff08;實型&#xff09; 有效位數保留七位&#xff0c;帶小數點。 這個是保…

構建安全的Docker基礎鏡像:從最佳實踐到自動化加固

引言 容器化技術的普及使得Docker鏡像成為軟件交付的核心載體,但鏡像中的安全漏洞、敏感信息泄露和權限配置不當等問題可能引發嚴重風險。本文結合OWASP容器安全指南與一線運維經驗,系統化講解如何構建安全的Docker基礎鏡像,覆蓋鏡像構建、依賴管理、運行時防護全鏈路,并提…

BKA-CNN基于黑翅鳶算法優化卷積神經網絡的數據多特征分類預測Matlab

BKA-CNN基于黑翅鳶算法優化卷積神經網絡的數據多特征分類預測Matlab 目錄 BKA-CNN基于黑翅鳶算法優化卷積神經網絡的數據多特征分類預測Matlab分類效果基本介紹BKA-CNN基于黑翅鳶算法優化卷積神經網絡的數據多特征分類預測一、引言1.1、研究背景和意義1.2、研究現狀1.3、研究目…

SOLID Principle基礎入門

(Robert C. Martin (Uncle Bob)) 什么是SOLID原則&#xff1f; SOLID原則是面向對象編程&#xff08;OOP&#xff09;中編寫高質量代碼的指導方針。實際上&#xff0c;即使不使用SOLID原則&#xff0c;僅通過類、繼承、封裝和多態性&#xff0c;也可以讓程序正常運行。那么為…

輕松實現語音生成:GPT-SoVITS V2整合包的遠程訪問操作詳解

文章目錄 前言1.GPT-SoVITS V2下載2.本地運行GPT-SoVITS V23.簡單使用演示4.安裝內網穿透工具4.1 創建遠程連接公網地址 5. 固定遠程訪問公網地址 前言 今天要給大家安利一個絕對能讓你大呼過癮的聲音黑科技——GPT-SoVITS&#xff01;這款由花兒不哭大佬精心打造的語音克隆神…

Python線程池知多少

目錄 目標 Python版本 官方文檔 概述 線程池 實戰 創建線程池的基本語法 批量提交任務 生產者&消費者模型 目標 掌握線程池的基本概念和使用方法。 Python版本 Python 3.9.18 官方文檔 concurrent.futures — Launching parallel taskshttps://docs.python.org/3…

(轉)SpringBoot和SpringCloud的區別

&#xff08;轉&#xff09;SpringBoot和SpringCloud的區別&#xff1a;

中科大 計算機網絡組成原理 1.4 接入網和物理媒體 筆記

一、接入網核心功能與架構 ?核心作用? 接入網是連接用戶終端與核心網絡的橋梁&#xff0c;承擔用戶身份認證、帶寬分配、數據加密等功能&#xff0c;直接影響網絡服務的可靠性和用戶體驗。例如&#xff0c;杭州電視臺的數字人主播通過光纖專線實現零失誤新聞播報&#xff0c;…

阿里云音頻算法崗內推

1、視頻云直播、連麥&#xff0c;點播&#xff0c;短視頻&#xff0c;媒體生產與處理等服務相關的實時/非實時的音頻分析和處理&#xff1b; 2、音頻處理算法&#xff0c;包括多場景降噪、自動增益控制、回聲消除等&#xff1b; 3、音頻特效算法研發&#xff0c;包括變調變速…

如何使用DeepSeek輔助準備面試

前言 又到了金三銀四的時間點了。每年的這個時間點都會出現無數的機遇和機會&#xff0c;但是如何準備面試&#xff0c;應該準備哪些面試題&#xff0c;如何查漏補缺我們的技術面的短板&#xff0c;這是我們每次準備面試的時候&#xff0c;都會遇見的問題。在今年&#xff0c;…

如何流暢訪問github

1.傳輸數據原理 本地計算機通過本地網接入運營骨干網&#xff0c;經過DNS域名解析&#xff0c;將輸入的字符解析為要連接的真實IP地址&#xff0c;服務器返還一個數據包(github)給計算機 2.原因 DNS域名污染-DNS解析出現問題&#xff0c;導致訪問一個不存在的服務器 3.解決…

JPA屬性轉換器的使用與實例解析

在Java持久化框架中&#xff0c;JPA&#xff08;Java Persistence API&#xff09;為我們提供了強大的功能來操作數據庫。其中&#xff0c;屬性轉換器&#xff08;Attribute Converter&#xff09;是一個非常實用的特性&#xff0c;它允許我們將實體類中的屬性類型轉換為適合存…

AI數據分析:用DeepSeek做數據清洗

在當今數據驅動的時代&#xff0c;數據分析已成為企業和個人決策的重要工具。隨著人工智能技術的快速發展&#xff0c;AI 驅動的數據分析工具正在改變我們處理和分析數據的方式。本文將著重介紹如何使用 DeepSeek 進行數據清洗。 數據清洗是數據分析的基礎&#xff0c;其目的是…

rust學習~tokio的io

await Suspend execution until the result of a Future is ready. 暫停執行&#xff0c;直到一個 Future 的結果就緒。 .awaiting a future will suspend the current function’s execution until the executor has run the future to completion. 對一個 Future 使用 .awa…

騰訊2025年軟件測試面試題

以下是基于騰訊等一線互聯網公司軟件測試崗位的面試趨勢和技術要求,025年出現的軟件測試面試題。這些問題涵蓋了基礎知識、自動化測試、性能測試、安全測試、編程能力等多個方面,供參考和準備。 一、基礎知識 軟件測試的基本概念

數據結構(陳越,何欽銘) 第四講 樹(中)

4.1 二叉搜索樹 4.1.1 二叉搜索樹及查找 Position Find(ElementTyoe X,BinTree BST){if(!BST){return NULL;}if(X>BST->Data){return Find(X,BST->Right)}else if(X<BST->Data){return Find(X,BST->Left)}else{return BST;} } Position IterFind(ElementTyp…

GEE學習筆記 28:基于Google Earth Engine的Landsat8纓帽變換土壤指數反演——亮度、綠度與濕度分量的提取

1.纓帽變換介紹 纓帽變換(Tasseled Cap Transformation,TCT),也稱為纓帽特征空間或纓帽系數,是一種用于遙感圖像分析的線性變換方法。它最初由美國農業部的研究人員E. Kauth和G. Thomas在1976年提出,用于增強陸地衛星(Landsat)圖像中的特定地表特征,如植被、土壤和城市…

【現代Web布局與動畫技術:卡片組件實戰分享】

&#x1f4f1; 現代Web布局與動畫技術&#xff1a;卡片組件實戰分享 &#x1f680; 引言 &#x1f31f; 在過去的開發過程中&#xff0c;我們共同實現了一個功能豐富的卡片組件&#xff0c;它不僅美觀&#xff0c;還具有交互性和響應式設計。這篇文章將分享這個組件背后的技術…

學習路之PHP --TP6異步執行功能 (無需安裝任何框架)

學習路之PHP --異步執行功能 &#xff08;無需安裝任何框架&#xff09; 簡介一、工具類二、調用三、異步任務的操作四、效果&#xff1a; 簡介 執行異步任務是一種很常見的需求&#xff0c;如批量發郵箱&#xff0c;短信等等執行耗時任務時&#xff0c;需要程序異步執行&…