linux下tcp/ip網絡通信筆記1,

本文章主要為博主在學習網絡通信的筆記+一個Udp_echo_server,和client的代碼實現

1,網絡發展,網絡協議,意識到網絡通信——不同主機的進程間通信,

2,學習如何在應用層調用系統提供的接口進行通信,echo_Udp_server, Udp_client,

目錄

一,學的時候找別人的資源過一遍這些概念就好?

二,貼點代碼,

InetAddr.hpp

common.hpp

Server.hpp

Server_main.cpp

Client_main.hpp

makefile



一,學的時候找別人的資源過一遍這些概念就好?

????????????????以下個人理解,未必和發展歷史相關,因果正確,博主建議概念性的知識你找別人看,博主的筆記僅僅為了給自己后期復習提醒一下,有些抽象和忽略,

發展/背景:局域網->廣域網,主機數量變多,距離變遠,各個要連接起來的局域網的協議不同,但卻要組織起來進行通信,所以再次分層/包裝->網絡層,

下面列些概念性的,懶得往這里搬了,

1,縱向分層,橫向模塊

2,port端口號——主機在網絡通信這塊兒區別進程的標識符,

? ? ? Ip地址——主機在網絡里的標識符,

? ? ? Mac地址——主機在局域網的標識符,

3,

? ? ??

???????????????

二,貼點代碼,

博主在寫的時候遇見最大的坑是ip轉了兩次(一次點分十進制轉網絡(inet_pton函數)一次在自己包裝的inetaddr里也處理了一次(htonl函數)),導致出錯, ,用到的系統調用的函數較少,代碼量少,就這樣了,跨過了/寫過了,就覺得這echo_server和client也就那樣,

InetAddr.hpp
#pragma once
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include "common.hpp"
// 就把這個class當包裝好的sockaddr_in用
// 主要是ip,port 本地轉網絡填socket, 網絡轉本地已經轉好
class InetAddr{
private:void PortNet2Host(){ _port = ntohs(_addr.sin_port); }void IpNet2Host(){ char buf[64] = { 0 };const char* ip = inet_ntop(AF_INET, &_addr.sin_addr.s_addr, buf, sizeof(buf));_ip = ip; }
public:InetAddr(){memset(&_addr, 0, sizeof(_addr));}InetAddr(struct sockaddr_in& addr){   memset(&_addr, 0, sizeof(_addr));_addr.sin_family = addr.sin_family;_addr.sin_addr.s_addr = addr.sin_addr.s_addr;_addr.sin_port = addr.sin_port;Init();}InetAddr(uint32_t ip, uint16_t port){// ip = htonl(ip);port = htons(port);memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;_addr.sin_addr.s_addr = ip;_addr.sin_port = port;// 由_addr去設置_ip和_portInit();}InetAddr(uint16_t port){port = htons(port);memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;_addr.sin_addr.s_addr = INADDR_ANY;_addr.sin_port = port;Init();}void Init(){PortNet2Host();IpNet2Host();}struct sockaddr* Sockaddr_in(){ return CONV(&_addr); }socklen_t Socklen() { return sizeof(_addr); }std::string Ip(){ return _ip; }uint16_t Port(){ return _port; }~InetAddr(){}private:struct sockaddr_in _addr;std::string _ip = "";uint16_t _port = 0;
};
common.hpp
#pragma once#include <iostream>#define Die(code)   \do              \{               \exit(code); \} while (0)#define CONV(v) (struct sockaddr *)(v)enum 
{USAGE_ERR = 1,SOCKET_ERR,BIND_ERR,RECVFORM_ERR,SENDTO_ERR
};
Server.hpp
#pragma once
#include <iostream>
#include <functional>#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include "InetAddr.hpp"
#include "common.hpp"
// ipv4 Udp EchoServer// 服務器需要,自己設置的port,ip寫INADDR_ANY,
// 1 socket, 
// 2 bind
// 3 調用recvfrom()與sendto()開始通信
// 我需要設計一個class server, 給它指定的port,它能自己socket并bind, 要有start函數去使用recvfrom,sendto去通信
// 我還要一個class, 給它sockaddr_in, 它讓我直接看到ip的點分十進制, 給它port, ip = INADDR_ANY,能吐出sockaddr_in.// server class == 一個運行的server, 
using func_t = std::function<std::string(const std::string&)>;
#define INIT_PORT 8080class UdpServer{
public:UdpServer(uint16_t port = INIT_PORT, func_t func = [](const std::string& s1){return s1;}):_addr(INADDR_ANY, port){_func = func;}void Init(){// 建文件描述符_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(_sockfd < 0){Die(SOCKET_ERR);}if(bind(_sockfd, _addr.Sockaddr_in(), _addr.Socklen())){Die(BIND_ERR);}}void start(){_isrunning = true;std::cout << "start_server ~\n" << "wait client send messsge!" << std::endl;while(1){InetAddr client_sockaddr;char buf[1024] = { 0 };socklen_t size = client_sockaddr.Socklen();int n = recvfrom(_sockfd, buf, sizeof(buf) - 1, 0, client_sockaddr.Sockaddr_in(), &size);if(n < 0){Die(RECVFORM_ERR);}std::string s(buf);client_sockaddr.Init();std::cout << client_sockaddr.Ip() << ":" << client_sockaddr.Port() << ": " << s << std::endl;// s = _func(s);//n = sendto(_sockfd, s.c_str(), s.size(), 0, client_sockaddr.Sockaddr_in(), client_sockaddr.Socklen());if(n < 0){Die(SENDTO_ERR);}}_isrunning = false;}
private:int _sockfd = -1;InetAddr _addr; // 只存個自己的socketbool _isrunning = false; // 服務器運行狀態// 業務func_t _func;
};
Server_main.cpp
#include "Server.hpp"
#include <functional>
#include <memory>
int main(int argc, char* argv[]){if(argc != 2){std::cout << "die~\n";Die(-1);}uint16_t port = atoi(argv[1]);std::unique_ptr<UdpServer> svr_uptr = std::make_unique<UdpServer>(port);svr_uptr->Init();std::cout << "Init_server ~\n";svr_uptr->start();return 0;
}
Client_main.hpp

#include <iostream>#include "common.hpp"
#include "InetAddr.hpp"int main(int argc, char* argv[]){if(argc != 3){exit(-1);}uint32_t ip = 0;inet_pton(AF_INET, argv[1], &ip);uint16_t port = atoi(argv[2]);InetAddr aim_server_addr(ip, port);int _fd = socket(AF_INET, SOCK_DGRAM, 0);while(1){std::cout << "Please Enter# " << std::endl;std::string s;socklen_t size = aim_server_addr.Socklen();std::getline(std::cin, s);int n = sendto(_fd, s.c_str(), s.size(), 0, aim_server_addr.Sockaddr_in(), aim_server_addr.Socklen());if(n < 0){Die(SENDTO_ERR);}std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;char buf[1024] = { 0 }; n = recvfrom(_fd, buf, sizeof(buf) - 1, 0, aim_server_addr.Sockaddr_in(), &size);if(n > 0){buf[n] = 0;std::cout << buf << std::endl;}}return 0;
}
makefile
.PHONY:all
all:server_udp client_udpserver_udp:Server_main.cppg++ -o $@ $^ -std=c++17
client_udp:Client_main.cppg++ -o $@ $^ -std=c++17.PHONY:clean
clean:rm -f server_udp client_udp

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

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

相關文章

前端二進制數據指南:從 ArrayBuffer 到高級流處理

前端開發中&#xff0c;二進制數據是處理文件、圖像、音視頻、網絡通信等場景的基礎。以下是核心概念和用途的通俗解釋&#xff1a; 前端二進制數據介紹 1. 什么是前端二進制數據&#xff1f; 指計算機原始的 0 和 1 格式的數據&#xff08;比如一張圖片的底層代碼&#xff…

Cacti 未經身份驗證SQL注入漏洞

0x00 前言 Cacti是一套基于PHP,MySQL,SNMP及RRDTool開發的網絡流量監測圖形分析工具。 Cacti是通過 snmpget來獲取數據&#xff0c;使用 RRDtool繪畫圖形&#xff0c;而且你完全可以不需要了解RRDtool復雜的參數。 0x01 漏洞描述 漏洞存在于從graph_view.php文件調用的growt…

使用國內源加速Qt在線安裝

簡介&#xff1a; 在線安裝Qt時&#xff0c;會發現下載非常緩慢&#xff0c;可以用過使用國內鏡像源來加速安裝過程。 在線安裝包的下載過程&#xff1a; 1&#xff0c;打開下載頁面 https://www.qt.io/download-open-source 2&#xff0c;點擊 Download the Qt online ins…

C#上位機RS485通信控制變頻器

C#上位機使用Modbus RTU協議控制變頻器 一、RTU報文格式示例 通信命令碼&#xff1a; 03H:讀從機參數 06H:寫從機參數 10H:寫多個參數上位機寫單個寄存器&#xff1a;【從機地址】1字節【命令碼】1字節【寄存器地址高-低】2字節【數據值高-低】2字節【CRC校驗值低-高】…

OCC筆記:Brep格式

1. BREP格式簡介 BREP格式是Open CASCADE內核&#xff08;OCCT&#xff09;的原生數據模型&#xff0c;直接描述幾何體的邊界表示&#xff08;面、邊、頂點拓撲關系及幾何參數&#xff09;。于OCCT內核的算法計算&#xff08;如布爾運算、曲面細分&#xff09;&#xff0c;存儲…

Vue3進行工程化項目,保姆級教學(編譯軟件:vscode)大部分編譯平臺適用

目錄 1. 創建vue工程 1.1 第一步 1.2 選擇名稱和工件 1.3 選擇語言 1.4 自動下載js 1.5 運行vue工程 1.6 成功頁面 2. 更改vue工程安裝的位置 3. 更改運行工程方式 第一步 第二步 ?編輯 第三步 調試 ?編輯 運行項目 前面所學都是vue3的基礎&#xff0c;為了簡…

CSS常用選擇器

CSS選擇器用于選擇HTML元素并為其應用樣式。以下是CSS中最常用的選擇器類型&#xff1a; 基本選擇器 1.元素選擇器 - 通過HTML標簽名選擇元素 p { color: blue; } 2.類選擇器 - 通過class屬性選擇元素&#xff08;以.開頭&#xff09; .warning { color: red; } 3.ID選擇…

EmberGen導出序列圖到UE5

選擇Render節點 調整節點相關參數 然后選擇一個目錄 點擊導出Export Now即可 材質用FlipBook 如果是特效就SubUV

EXCEL Python 實現繪制柱狀線型組合圖和樹狀圖(包含數據透視表)

1、組合圖、數據透視表 &#xff08;1&#xff09;數據預處理 知識點 日期函數 year() month()數據透視表操作 同比計算公式 環比計算公式 &#xff08;2&#xff09;excel 數據透視表插入組合圖 a.2015~2017數據集處理方式&#xff1a; 操作&#xff1a; 結果 b.2020~20…

LabVIEW光譜檢測系統

腔衰蕩光譜技術&#xff08;CRDS&#xff09;憑借高精度和高靈敏度特性&#xff0c;成為微量氣體濃度檢測的常用方法&#xff0c;而準確獲取衰蕩時間是該技術應用的關鍵。基于LabVIEW平臺設計腔衰蕩信號在線處理系統&#xff0c;實現對衰蕩信號的實時采集、平均、擬合、顯示和保…

Flask快速入門和問答項目源碼

Flask基礎入門 源碼&#xff1a; gitee&#xff1a;我愛白米飯/Flask問答項目 - 碼云 目錄 1.安裝環境2.【debug、host、port】3.【路由params和query】4.【模板】5.【靜態文件】6.【數據庫連接】6.1.安裝模塊6.2.創建數據庫并測試連接6.3.創建數據表6.4.ORM增刪改查 6.5.ORM模…

flutter長列表 ListView、GridView、SingleChildScrollView、CustomScrollView區別

組件名稱用途/適合場景是否懶加載支持列表結構用法復雜度SingleChildScrollView適用于內容數量不大、不重復的頁面&#xff08;如表單、靜態內容&#xff09;? 否? 否??ListView適用于垂直方向的長列表&#xff0c;自動滾動&#xff1b;適合展示大量數據? 支持? 是??Li…

鴻蒙OSUniApp 開發的一鍵分享功能#三方框架 #Uniapp

使用 UniApp 開發的一鍵分享功能 在移動應用開發中&#xff0c;分享功能幾乎是必不可少的一環。一個好的分享體驗不僅能帶來更多用戶&#xff0c;還能提升產品的曝光度。本文將詳細講解如何在 UniApp 框架下實現一個簡單高效的一鍵分享功能&#xff0c;適配多個平臺。 各平臺分…

Vue-監聽屬性

監聽屬性 簡單監聽 點擊切換名字&#xff0c;來回變更Tom/Jerry&#xff0c;輸出 你好&#xff0c;Tom/Jerry 代碼 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>監聽屬性</title><!-- …

DeepSeek 賦能物聯網:從連接到智能的跨越之路

目錄 一、引言&#xff1a;物聯網新時代的開啟二、DeepSeek 技術揭秘2.1 DeepSeek 是什么2.2 DeepSeek 技術優勢 三、DeepSeek 與物聯網的融合之基3.1 物聯網發展現狀與挑戰3.2 DeepSeek 帶來的變革性突破 四、DeepSeek 在物聯網的多元應用場景4.1 智慧電力&#xff1a;開啟能源…

3.6/Q1,GBD數據庫最新文章解讀

文章題目&#xff1a;Global, regional, and national burden of geriatric depressive disorders in people aged 60 years and older: an analysis of the Global Burden of Disease Study 2021 DOI&#xff1a;10.1186/s12991-025-00560-2 中文標題&#xff1a;60 歲及以上人…

LVGL學習筆記

文章目錄 一、 LVGL移植教程(GD32)一 并行驅動 LED二三一、 LVGL移植教程(GD32) 參考鏈接 1.GD32+LVGL移植教程(超詳細)——基于GD32F303X系列MCU 一 并行驅動 LED 根據您提供的引腳信號(DCLK、DISP、HSYNC、VSYNC、DE),可以判斷這是一款采用 TTL/Parallel RGB 接口…

軟件架構之--論微服務的開發方法1

論微服務的開發方法1 摘要 2023年 2月,本人所在集團公司承接了長三角地區某省漁船圖紙電子化審查系統項目開發,該項目旨在為長三角地區漁船建造設計院、以及漁船圖紙審查機構提供一個便捷的漁船圖紙電子化審查服務平臺。在此項目中,我作為項目組成員參與項目的建設工作,并…

如何在終端/命令行中把PDF的每一頁轉換成圖片(PNG)

今天被對象安排了一個任務&#xff1a; 之前自己其實也有這個需要&#xff0c;但是吧&#xff0c;我懶&#xff1a;量少拖拽&#xff0c;量大就放棄。但這次躲不過去了&#xff0c;所以研究了一下有什么工具可以做到這個需求。 本文記錄我這次發現的使用 XpdfReader 的方法。…

mac安裝cast

背景 pycharm本地運行腳本時提示cast沒有安裝 問題原因 腳本嘗試調用cast命令&#xff08;以太坊開發工具foundry中的子命令&#xff09;&#xff0c;但您的系統未安裝該工具。 從日志可見&#xff0c;錯誤發生在通過sysutil.py執行shell命令時。 解決方案 方法1&#xf…