封裝Tcp Socket

封裝Tcp Socket

  • 0. 前言
  • 1. Socket.hpp
  • 2. 簡單的使用介紹


0. 前言


本文中用到的Log.hpp在筆者的歷史文章中都有涉及,這里就不再粘貼源碼了,學習地址如下:https://blog.csdn.net/weixin_73870552/article/details/145434855?spm=1001.2014.3001.5501。

TCP相對于UDP更加復雜,這里只介紹TCP的封裝,學習完后,大家可以自己嘗試UDP的封裝。


1. Socket.hpp


采用模版方法類的設計模式,基類方法由子類實現

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>#define Convert(addrptr) ((struct sockaddr*)addrptr)// 錯誤碼
enum {SocketError = 1,BindError,ListenError
};const static int defaultsockfd = -1;
const int backlog = 5;      // 這個參數后面講// 封裝一個基類,Socket接口類
// 設計模式:模版方法類
class Socket
{
public:virtual ~Socket() {}virtual void CreateSocketOrDie() = 0;               // 創建套接字virtual void BindSocketOrDie(uint16_t port) = 0;    // 綁定virtual void ListenSocketOrDie(int backlog) = 0;    // 監聽virtual Socket* AcceptConnection(std::string *peerip, uint16_t *peerport) = 0; virtual bool ConnectServer(std::string &serverip, uint16_t serverport) = 0;virtual int GetSockFd() = 0;virtual void SetSockFd(int sockfd) = 0;virtual void CloseSocket() = 0;virtual bool Recv(std::string *buffer, int size) = 0;virtual void Send(std::string &send_str) = 0;
public:void BuildListenSocketMethod(uint16_t port, int backlog){CreateSocketOrDie();BindSocketOrDie(port);ListenSocketOrDie(backlog);}bool BuildConnectSocketMethod(std::string &serverip, uint16_t serverport){CreateSocketOrDie();return ConnectServer(serverip, serverport);}void BuildNormalSocketMethod(int sockfd){SetSockFd(sockfd);}
};// TCP
class TcpSocket : public Socket
{
public:TcpSocket(int sockfd = defaultsockfd): _sockfd(sockfd){}~TcpSocket(){}void CreateSocketOrDie() override{_sockfd = ::socket(AF_INET, SOCK_STREAM, 0);if(_sockfd < 0) exit(SocketError);}void BindSocketOrDie(uint16_t port) override{struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_addr.s_addr = INADDR_ANY;local.sin_port = htons(port);int n = ::bind(_sockfd, Convert(&local), sizeof(local));if(n < 0) exit(BindError);}void ListenSocketOrDie(int backlog) override{int n = ::listen(_sockfd, backlog);if(n < 0) exit(ListenError);}Socket* AcceptConnection(std::string *peerip, uint16_t *peerport) override{struct sockaddr_in peer;socklen_t len = sizeof(peer);int newsockfd = ::accept(_sockfd, Convert(&peer), &len);if(newsockfd < 0) return nullptr;*peerip = inet_ntoa(peer.sin_addr);*peerport = ntohs(peer.sin_port);Socket *s = new TcpSocket(newsockfd);return s;}bool ConnectServer(std::string &serverip, uint16_t serverport) override{struct sockaddr_in server;memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_addr.s_addr = inet_addr(serverip.c_str());server.sin_port = htons(serverport);int n = ::connect(_sockfd, Convert(&server), sizeof(server));if(n == 0) return true;else return false;}int GetSockFd() override{return _sockfd;}void SetSockFd(int sockfd) override{_sockfd = sockfd;}void CloseSocket() override{if(_sockfd > defaultsockfd) ::close(_sockfd);}bool Recv(std::string *buffer, int size) override{char inbuffer[size];ssize_t n = recv(_sockfd, inbuffer, size-1, 0);if(n > 0){inbuffer[n] = 0;*buffer += inbuffer; return true;}else if(n == 0) return false;else return false;}void Send(std::string &send_str) override{// 這一塊涉及到多路轉接,我們之后統一說send(_sockfd, send_str.c_str(), send_str.size(), 0);}private:int _sockfd;
};

2. 簡單的使用介紹


1. 服務端

#include <iostream>
#include <string>
#include <memory>
#include <unistd.h>
#include "Log.hpp"
#include "Socket.hpp"// ./server localport
int main(int argc, char *argv[])
{if(argc != 2){std::cout << "Usage: " << argv[0] << "port" << std::endl;return 0;}uint16_t localport = std::stoi(argv[1]);std::unique_ptr<TcpSocket> tsvr(new TcpSocket());tsvr->BuildListenSocketMethod(localport, backlog);while(true){std::string peerip;uint16_t peerport;lg.LogMessage(Debug, "ready to accept, listensocketfd: %d\n", tsvr->GetSockFd());Socket *newsock = tsvr->AcceptConnection(&peerip, &peerport);if(newsock == nullptr) continue;lg.LogMessage(Info, "get a new link... sockfd: %d, client info: %s:%d\n", newsock->GetSockFd(), peerip.c_str(), peerport);while(true){std::string buffer;newsock->Recv(&buffer, 1024);std::cout << "get a message: " << buffer.c_str() << std::endl;sleep(1);}// 注意資源的釋放newsock->CloseSocket();delete newsock;}tsvr->CloseSocket();return 0;
}

2. 客戶端

#include <iostream>
#include <unistd.h>
#include <memory>
#include "Socket.hpp"// ./client serverip serverport
int main(int argc, char* argv[])
{if(argc != 3){std::cout << "Usage: " << argv[0] << " serverip serverport" << std::endl;return 0;}std::string serverip = argv[1];uint16_t serverport = std::stoi(argv[2]);std::unique_ptr<TcpSocket> tsvr(new TcpSocket());if(!tsvr->BuildConnectSocketMethod(serverip, serverport)){std::cerr << "connect " << serverip << ":" << serverport << " failed" << std::endl;return 0;}std::cout << "connect " << serverip << ":" << serverport << " success" << std::endl;std::string message = "a";char n = 'b';while(true){tsvr->Send(message);message.push_back(n++);sleep(1);}tsvr->CloseSocket();return 0;
}

3. 通信測試

在這里插入圖片描述


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

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

相關文章

全星APQP軟件:為用戶提供高效、合規、便捷的研發管理體驗

全星APQP軟件&#xff1a;為用戶提供高效、合規、便捷的研發管理體驗 為什么選擇全星APQP軟件系統&#xff1f; 在汽車及高端制造行業&#xff0c;研發項目管理涉及APQP&#xff08;先期產品質量策劃&#xff09;、FMEA&#xff08;失效模式與影響分析&#xff09;、CP&#x…

CTF--網站被黑

一、原題&#xff1a; &#xff08;1&#xff09;提示&#xff1a;網站被黑了 黑客會不會留下后門 &#xff08;2&#xff09;原網頁&#xff1a; 二、步驟&#xff1a; 1.在終端掃描網址&#xff1a; 2.掃描后發現&#xff1a;shell.php 3.輸入網址&#xff1a;http://117.…

入門到精通,C語言十大經典程序

以下是十個經典的C語言程序示例&#xff0c;這些程序涵蓋了從基礎到稍復雜的應用場景&#xff0c;適合初學者和有一定基礎的開發者學習和參考。 1. Hello, World! 這是每個初學者學習編程時的第一個程序&#xff0c;用于驗證開發環境是否正確配置。 #include <stdio.h>…

神經網絡入門—自定義神經網絡續集

修改網絡 神經網絡入門—自定義網絡-CSDN博客 修改數據集&#xff0c;yx^2 # 生成一些示例數據 x_train torch.tensor([[1.0], [2.0], [3.0], [4.0]], dtypetorch.float32) y_train torch.tensor([[1.0], [4.0], [9.0], [16.0]], dtypetorch.float32) 將預測代碼改為&…

【browser-use+deepseek】實現簡單的web-ui自動化

browser-use Web-UI 一、browser-use是什么 Browser Use 是一款開源Python庫&#xff0c;專為大語言模型設計的智能瀏覽器工具&#xff0c;目的是讓 AI 能夠像人類一樣自然地瀏覽和操作網頁。它支持多標簽頁管理、視覺識別、內容提取&#xff0c;并能記錄和重復執行特定動作。…

Vue--常用組件解析

綁定事件v-on和按鍵修飾符 v-on:click 表示在button元素上監聽click事件 簡寫&#xff1a;click enter space tab 按鍵修飾符 keyup是用戶松開按鍵才觸發 keydown是在用戶按下按鍵時立即觸發 代碼展示&#xff1a; <!DOCTYPE html><html lang"en" xml…

《JVM考古現場(十八):造化玉碟·用字節碼重寫因果律的九種方法》

"鴻蒙初判&#xff01;當前因果鏈突破十一維屏障——全體碼農修士注意&#xff0c;《JVM考古現場&#xff08;十八&#xff09;》即將渡劫飛升&#xff01;" 目錄 上卷陰陽交纏 第一章&#xff1a;混沌初開——JVM因果律的量子糾纏 第二章&#xff1a;誅仙劍陣改—…

前端vue 項目px轉為rem的自適應解決方案

postcss-pxtorem&#xff08;或是postcss-px2rem&#xff09; npm install postcss-pxtorem amfe-flexible --save-dev 在入口文件 main.js 中引入 amfe-flexible&#xff08;響應式適配&#xff09;&#xff1a; main.js import amfe-flexible // 自動設置 html 的 font-s…

基于時間序列分解與XGBoost的交通通行時間預測方法解析

一、問題背景與數據概覽 在城市交通管理系統中,準確預測道路通行時間對于智能交通調度和路徑規劃具有重要意義。本文基于真實道路傳感器數據,構建了一個結合時間序列分解與機器學習模型的預測框架。數據源包含三個核心部分: 道路通行數據(new_gy_contest_traveltime_train…

Day14:關于MySQL的索引——創、查、刪

前言&#xff1a;先創建一個練習的數據庫和數據 1.創建數據庫并創建數據表的基本結構 -- 創建練習數據庫 CREATE DATABASE index_practice; USE index_practice;-- 創建基礎表&#xff08;包含CREATE TABLE時創建索引&#xff09; CREATE TABLE products (id INT PRIMARY KEY…

【C++】繼承:萬字總結

&#x1f4dd;前言&#xff1a; 這篇文章我們來講講面向對象三大特性之一——繼承 &#x1f3ac;個人簡介&#xff1a;努力學習ing &#x1f4cb;個人專欄&#xff1a;C學習筆記 &#x1f380;CSDN主頁 愚潤求學 &#x1f304;其他專欄&#xff1a;C語言入門基礎&#xff0c;py…

Java 架構設計:從單體架構到微服務的轉型之路

Java 架構設計&#xff1a;從單體架構到微服務的轉型之路 在現代軟件開發中&#xff0c;架構設計的選擇對系統的可擴展性、可維護性和性能有著深遠的影響。隨著業務需求的日益復雜和用戶規模的不斷增長&#xff0c;傳統的單體架構逐漸暴露出其局限性&#xff0c;而微服務架構作…

Django3 - 開啟Django Hello World

一、開啟Django Hello World 要學習Django首先需要了解Django的操作指令&#xff0c;了解了每個指令的作用&#xff0c;才能在MyDjango項目里編寫Hello World網頁&#xff0c;然后通過該網頁我們可以簡單了解Django的開發過程。 1.1 Django的操作指令 無論是創建項目還是創建項…

2025阿里云AI 應用-AI Agent 開發新范式-MCP最佳實踐-78頁.pptx

2025阿里云AI 應用-AI Agent 開發新范式-MCP最佳實踐&#xff0c;包含以下內容&#xff1a; 1、AI 應用架構新范式 2、云原生API網關介紹 3、云原生API網關底座核心優勢 4、流量網關最佳實踐 5、AI 網關代理 LLM 最佳實踐 6、MCP網關最佳實踐 7、MSE Nacos MCP Server 注冊中心…

Pytorch深度學習框架60天進階學習計劃 - 第41天:生成對抗網絡進階(一)

Pytorch深度學習框架60天進階學習計劃 - 第41天&#xff1a;生成對抗網絡進階&#xff08;一&#xff09; 今天我們將深入探討生成對抗網絡(GAN)的進階內容&#xff0c;特別是Wasserstein GAN&#xff08;WGAN&#xff09;的梯度懲罰機制&#xff0c;以及條件生成與無監督生成…

大模型到底是怎么產生的?一文了解大模型誕生全過程

前言 大模型到底是怎么產生的呢? 本文將從最基礎的概念開始,逐步深入,用通俗易懂的語言為大家揭開大模型的神秘面紗。 大家好,我是大 F,深耕AI算法十余年,互聯網大廠核心技術崗。 知行合一,不寫水文,喜歡可關注,分享AI算法干貨、技術心得。 【專欄介紹】: 歡迎關注《…

五子棋(測試報告)

文章目錄 一、項目介紹二、測試用例三、自動化測試用例的部分展示注冊登錄游戲大廳游戲匹配 總結 一、項目介紹 本項目是一款基于Spring、SpringMVC、MyBatis、WebSocket的雙人實時對戰五子棋游戲,游戲操作便捷&#xff0c;功能清晰明了。 二、測試用例 三、自動化測試用例的…

idea開發工具多賬號使用拉取代碼報錯問題

設置git不使用憑證管理 把 use credential helper 取消勾選 然后重新pull代碼&#xff0c;并勾選remember 這樣就可以使用多賬號來連接管理代碼了

【OpenCV】【XTerminal】talk程序運用和linux進程之間通信程序編寫,opencv圖像庫編程聯系

目錄 一、talk程序的運用&Linux進程間通信程序的編寫 1.1使用talk程序和其他用戶交流 1.2用c語言寫一個linux進程之間通信&#xff08;聊天&#xff09;的簡單程序 1.服務器端程序socket_server.c編寫 2.客戶端程序socket_client.c編寫 3.程序編譯與使用 二、編寫一個…

【軟考系統架構設計師】信息系統基礎知識點

1、 信息的特點&#xff1a;客觀性&#xff08;真偽性&#xff09;、動態性、層次性、傳遞性、滯后性、擴壓性、分享性 2、 信息化&#xff1a;是指從工業社會到信息社會的演進與變革 3、 信息系統是由計算機硬件、網絡和通信設備、計算機軟件、信息資源、信息用戶和規章制度…