C++ - 網絡編程之初始連接(Winsock2 概述、初始連接案例、初始連接案例解讀)

一、Winsock2 概述

  • Winsock2(Windows Sockets 2)是微軟提供的 Windows 平臺網絡編程庫

二、初始連接案例

1、Server
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>#pragma comment(lib, "ws2_32.lib")using namespace std;const int listen_port = 12345;int main() {WSADATA wsaData;int WSAStartupResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (WSAStartupResult != 0) {cerr << "WSAStartup() failed: " << WSAStartupResult << endl;return 1;}SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (listenSocket == INVALID_SOCKET) {cerr << "socket() failed: " << WSAGetLastError() << endl;WSACleanup();return 1;}sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(listen_port);serverAddr.sin_addr.s_addr = INADDR_ANY;int bindResult = bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));if (bindResult == SOCKET_ERROR) {cerr << "bind() failed: " << WSAGetLastError() << endl;closesocket(listenSocket);WSACleanup();return 1;}if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {cerr << "listen() failed: " << WSAGetLastError() << endl;closesocket(listenSocket);WSACleanup();return 1;}cout << "Server is listening on port " << listen_port << endl;sockaddr_in clientAddr;int clientAddrSize = sizeof(clientAddr);SOCKET clientSocket = accept(listenSocket, (sockaddr*)&clientAddr, &clientAddrSize);if (clientSocket == INVALID_SOCKET) {cerr << "accept() failed: " << WSAGetLastError() << endl;}char clientIP[INET_ADDRSTRLEN];inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);cout << "Client connected from " << clientIP << ":" << ntohs(clientAddr.sin_port) << endl;return 0;
}
2、Client
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>#pragma comment(lib, "ws2_32.lib")using namespace std;int main() {WSADATA wsaData;int WSAStartupResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (WSAStartupResult != 0) {cerr << "WSAStartup() failed: " << WSAStartupResult << endl;return 1;}SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET) {cerr << "socket() failed: " << WSAGetLastError() << endl;WSACleanup();return 1;}sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(12345);inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);int ConnectionResult = connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));if (ConnectionResult == SOCKET_ERROR) {cerr << "connect() failed: " << WSAGetLastError() << endl;closesocket(sock);WSACleanup();return 1;}cout << "Successfully connected to server!" << endl;closesocket(sock);WSACleanup();return 0;
}
3、Test
  1. 啟動 Server,輸出結果
# ServerServer is listening on port 12345
  1. 啟動 Client,輸出結果
# ClientSuccessfully connected to server!
# ServerClient connected from 127.0.0.1:63154

三、初始連接案例解讀

1、Server
(1)頭文件與庫引入
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>#pragma comment(lib, "ws2_32.lib")using namespace std;
  1. winsock2.h 是 Winsock 編程的核心頭文件,包含了大部分套接字函數和數據結構的定義

  2. ws2tcpip.h 提供 IP 地址轉換等功能

  3. iostream 標準輸入輸出

  4. #pragma comment 指令用于鏈接 ws2_32.lib

  5. using namespace 啟用命名空間 std

(2)初始化 Winsock 庫
WSADATA wsaData;
int WSAStartupResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (WSAStartupResult != 0) {cerr << "WSAStartup() failed: " << WSAStartupResult << endl;return 1;
}
  1. WSADATA 結構用于接收庫的詳細信息

  2. WSAStartup() 是 Winsock 程序的第一個調用,用于初始化庫,MAKEWORD(2, 2) 表示初始化 Winsock 2.2 版本

  3. 必須檢查返回值,失敗時應立即退出

(3)創建監聽套接字
SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listenSocket == INVALID_SOCKET) {cerr << "socket() failed: " << WSAGetLastError() << endl;WSACleanup();return 1;
}
  1. socket() 用于創建套接字,失敗時返回 INVALID_SOCKET

  2. AF_INET 表示使用 IPv4 地址族,SOCK_STREAM 表示面向連接的 TCP 套接字,IPPROTO_TCP 表示指定 TCP 協議

  3. 失敗時調用 WSAGetLastError() 獲取錯誤代碼,然后調用 WSACleanup() 釋放資源

(4)設置服務端地址
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(listen_port);
serverAddr.sin_addr.s_addr = INADDR_ANY;
  1. sockaddr_in 結構用于指定服務器地址信息

  2. sin_family 表示地址族(IPv4),sin_port 表示端口號(使用 htons 將主機字節序轉換為網絡字節序),sin_addr.s_addr 使用的 INADDR_ANY 表示綁定到所有可用接口

(5)綁定套接字
int bindResult = bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (bindResult == SOCKET_ERROR) {cerr << "bind() failed: " << WSAGetLastError() << endl;closesocket(listenSocket);WSACleanup();return 1;
}
  1. bind() 將套接字與特定 IP 和端口關聯,如果未發生錯誤,綁定返回 0,否則,返回 SOCKET_ERROR

  2. 失敗時調用 WSAGetLastError() 獲取錯誤代碼,然后調用 closesocket() 關閉現有套接字,然后調用 WSACleanup() 釋放資源

(6)開始監聽
if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {cerr << "listen() failed: " << WSAGetLastError() << endl;closesocket(listenSocket);WSACleanup();return 1;
}cout << "Server is listening on port " << listen_port << endl;
  1. listen() 使套接字進入監聽狀態,如果未發生錯誤,返回 0,否則,返回 SOCKET_ERROR

  2. SOMAXCONN 是系統允許的最大掛起連接數

  3. 失敗時調用 WSAGetLastError() 獲取錯誤代碼,然后調用 closesocket() 關閉現有套接字,然后調用 WSACleanup() 釋放資源

(7)接受客戶端連接
sockaddr_in clientAddr;
int clientAddrSize = sizeof(clientAddr);
SOCKET clientSocket = accept(listenSocket, (sockaddr*)&clientAddr, &clientAddrSize);
if (clientSocket == INVALID_SOCKET) {cerr << "accept() failed: " << WSAGetLastError() << endl;
}
  1. clientAddr 結構用于獲取客戶端地址信息

  2. accept() 接受傳入的連接請求,阻塞直到有客戶端連接,返回一個新的套接字用于與客戶端通信

(8)顯示客戶端信息
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);
cout << "Client connected from " << clientIP << ":" << ntohs(clientAddr.sin_port) << endl;
  1. inet_ntop() 將二進制 IP 地址轉換為可讀字符串

  2. ntohs() 將網絡字節序的端口轉換為主機字節序

2、Client
(1)頭文件與庫引入
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>#pragma comment(lib, "ws2_32.lib")using namespace std;
  1. winsock2.h 是 Winsock 編程的核心頭文件,包含了大部分套接字函數和數據結構的定義

  2. ws2tcpip.h 提供 IP 地址轉換等功能

  3. iostream 標準輸入輸出

  4. #pragma comment 指令用于鏈接 ws2_32.lib

  5. using namespace 啟用命名空間 std

(2)初始化 Winsock 庫
WSADATA wsaData;
int WSAStartupResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (WSAStartupResult != 0) {cerr << "WSAStartup() failed: " << WSAStartupResult << endl;return 1;
}
(3)創建套接字
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {cerr << "socket() failed: " << WSAGetLastError() << endl;WSACleanup();return 1;
}
  1. socket() 用于創建套接字,失敗時返回 INVALID_SOCKET

  2. AF_INET 表示使用 IPv4 地址族,SOCK_STREAM 表示面向連接的 TCP 套接字,IPPROTO_TCP 表示指定 TCP 協議

  3. 失敗時調用 WSAGetLastError() 獲取錯誤代碼,然后調用 WSACleanup() 釋放資源

(4)設置服務端地址
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);
  1. sockaddr_in 結構用于指定服務器地址信息

  2. sin_family 表示地址族(IPv4),sin_port 表示端口號(使用 htons 將主機字節序轉換為網絡字節序),sin_addr 使用 inet_pton 將字符串 IP 轉換為二進制格式

(5)連接服務端
int ConnectionResult = connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (ConnectionResult == SOCKET_ERROR) {cerr << "connect() failed: " << WSAGetLastError() << endl;closesocket(sock);WSACleanup();return 1;
}
  1. connect() 發起連接,如果成功,返回 0,否則,返回 SOCKET_ERROR

  2. 失敗時調用 WSAGetLastError() 獲取錯誤代碼,然后調用 closesocket() 關閉現有套接字,然后調用 WSACleanup() 釋放資源

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

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

相關文章

Spring Cloud Gateway深度解析:原理、架構與生產實踐

文章目錄 前言一、概述二、核心架構設計及設計原理2.1 分層架構模型網絡層&#xff08;I/O模型&#xff09;核心處理層 2.2 核心組件協作流程路由定位階段過濾器執行階段 2.3 響應式編程模型實現Reactor上下文傳遞背壓處理機制 2.4 動態路由設計原理2.5 異常處理體系2.6 關鍵路…

游戲開發實戰(一):Python復刻「崩壞星穹鐵道」嗷嗚嗷嗚事務所---源碼級解析該小游戲背后的算法與設計模式【純原創】

文章目錄 奇美拉項目游戲規則奇美拉(Chimeras)檔案領隊成員 結果展示&#xff1a; 奇美拉項目 由于項目工程較大&#xff0c;并且我打算把我的思考過程和實現過程中踩過的坑都分享一下&#xff0c;因此會分3-4篇博文詳細講解本項目。本文首先介紹下游戲規則并給出奇美拉檔案。…

說一下響應狀態碼有哪些?

HTTP響應狀態碼分類(RFC 7231標準) 1. 1xx(信息類) 臨時響應,表示請求已被接收,需要繼續處理 100 Continue:客戶端應繼續發送請求體 101 Switching Protocols:服務器同意升級協議(如WebSocket) 102 Processing(WebDAV):服務器正在處理但未完成 2. 2xx(成功類)…

Linux多進程 寫時拷貝 物理地址和邏輯地址

如果不采用寫時拷貝技術 直接fork子進程 會發生什么&#xff1f; 如上圖所示 橙色為父進程所占內存空間 綠色為子進程所占內存空間。 如果子進程只是需要做出一點點和父進程不一樣的 其余和父進程均為相同 第一 就會出現復制開銷比較大&#xff1b;第二占用內存空間 所以 …

【TTS回顧】Bert-VITS2深度解析:融合BERT的多語言語音合成模型

一、基本介紹 Bert-VITS2是基于VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的改進版本,通過整合BERT語義編碼能力,顯著提升了語音合成的自然度和表現力。項目地址:https://github.com/fishaudio/Bert-VITS2 語種自然度相似度流…

win11下docker 的使用方案

Windows 11 Docker 使用方式對比 特性Docker Desktop (使用 WSL 2 后端)直接在 WSL 2 中安裝 Docker Engine安裝與易用性極簡&#xff0c;一鍵安裝&#xff0c;提供直觀的 GUI 界面 管理容器、鏡像、卷等相對復雜&#xff0c;需手動在 Linux 環境中安裝 Docker Daemon 并配置G…

配合本專欄前端文章對應的后端文章——從模擬到展示:一步步搭建傳感器數據交互系統

對應文章&#xff1a;進一步完善前端框架搭建及vue-konva依賴的使用&#xff08;Vscode&#xff09;-CSDN博客 目錄 一、后端開發 1.模擬傳感器數據 2.前端頁面呈現數據后端互通 2.1更新模擬傳感器數據程序&#xff08;多次請求&#xff09; 2.2&#x1f9e9; 功能目標 …

牛客網NC209794:使徒襲來

牛客網NC209794:使徒襲來 題目背景 問題分析 數學建模 設三位駕駛員的戰斗力分別為 a, b, c已知條件&#xff1a;a b c n (n為輸入的正整數)目標&#xff1a;求 a b c 的最小值 解題思路 根據算術-幾何平均值不等式(AM-GM不等式)&#xff0c;對于任意正實數a, b, c&a…

動態規劃之爬樓梯模型

文章目錄 爬樓梯模型LeetCode 746. 使用最小花費爬樓梯思路Golang 代碼 LeetCode 377. 組合總和 Ⅳ思路Golang 代碼 LeetCode 2466. 統計構造好字符串的方案數思路Golang 代碼 LeetCode 2266. 統計打字方案數思路Golang 代碼 爬樓梯模型 爬樓梯模型是動態規劃當中的一個經典模型…

【每天一個知識點】湖倉一體(Data Lakehouse)

“湖倉一體”&#xff08;Data Lakehouse&#xff09;是一種融合了數據湖&#xff08;Data Lake&#xff09;與數據倉庫&#xff08;Data Warehouse&#xff09;優勢的新型數據架構。它既繼承了數據湖對多類型數據的靈活存儲能力&#xff0c;也具備數據倉庫對結構化數據的高效查…

Linux | mdadm 創建軟 RAID

注&#xff1a;本文為 “Linux mdadm RAID” 相關文章合輯。 略作重排&#xff0c;未整理去重。 如有內容異常&#xff0c;請看原文。 Linux 下用 mdadm 創建軟 RAID 以及避坑 喵??&#xfecc;?? Oct 31, 2023 前言 linux 下組軟 raid 用 mdadm 命令&#xff0c;multi…

Unity自定義shader打包SpriteAtlas圖集問題

Unity打包圖集還是有一些坑的&#xff0c;至于圖集SpriteAtlas是什么請參考我之前寫的文章&#xff1a;【Sprite Atlas】Unity新圖集系統SpriteAtlas超詳細使用教程_spriteatlas 使用-CSDN博客 問題&#xff1a; 今天碰到的問題是&#xff0c;shader繪制的時候&#xff0c;因…

如何用 OceanBase 的 LOAD DATA 旁路導入進行大表遷移

前言 在日常工作中&#xff0c;我們時常會遇到需要將某個大數據量的單表進行遷移的情況。在MySQL中&#xff0c;針對這樣的大表&#xff0c;我們通常會選擇先將原表導出為csv格式&#xff0c;然后利用LOAD DATA語法來導入csv文件&#xff0c;這種方法相較于mysqldump在效率上有…

VR 互動實訓的顯著優勢?

&#xff08;一&#xff09;沉浸式學習&#xff0c;提升培訓效果? 在 VR 互動實訓中&#xff0c;員工不再是被動的知識接受者&#xff0c;而是主動的參與者。以銷售培訓為例&#xff0c;員工戴上 VR 設備&#xff0c;就能置身于逼真的銷售場景中&#xff0c;與虛擬客戶進行面對…

OpenCV 第6課 圖像處理之幾何變換(重映射)

1. 概述 簡單來說,重映射就是把一副圖像內的像素點按照規則映射到到另外一幅圖像內的對應位置上去,形成一張新的圖像。 因為原圖像與目標圖像的像素坐標不是一一對應的。一般情況下,我們通過重映射來表達每個像素的位置(x,y),像這樣: g(x,y)=f(h(x,y)) 在這里g()是目標圖…

Java虛擬機 - 程序計數器和虛擬機棧

運行時數據結構 Java運行時數據區程序計數器為什么需要程序計數器執行流程虛擬機棧虛擬機棧作用虛擬機棧核心結構運行機制 Java運行時數據區 首先介紹Java運行時數據之前&#xff0c;我們要了解&#xff0c;對于計算機來說&#xff0c;內存是非常重要的資源&#xff0c;因為內…

MySQL數據庫——支持遠程IP訪問的設置方法總結

【系列專欄】&#xff1a;博主結合工作實踐輸出的&#xff0c;解決實際問題的專欄&#xff0c;朋友們看過來&#xff01; 《項目案例分享》 《極客DIY開源分享》 《嵌入式通用開發實戰》 《C語言開發基礎總結》 《從0到1學習嵌入式Linux開發》 《QT開發實戰》 《Android開發實…

CSS- 4.6 radiu、shadow、animation動畫

本系列可作為前端學習系列的筆記&#xff0c;代碼的運行環境是在HBuilder中&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 HTML系列文章 已經收錄在前端專欄&#xff0c;有需要的寶寶們可以點擊前端專欄查看&#xff01; 點…

排序算法之基礎排序:冒泡,選擇,插入排序詳解

排序算法之基礎排序&#xff1a;冒泡、選擇、插入排序詳解 前言一、冒泡排序&#xff08;Bubble Sort&#xff09;1.1 算法原理1.2 代碼實現&#xff08;Python&#xff09;1.3 性能分析 二、選擇排序&#xff08;Selection Sort&#xff09;2.1 算法原理2.2 代碼實現&#xff…

第十節第一部分:常見的API:Math、System、Runtime

Math類介紹及常用方法&#xff08;了解知道即可&#xff09; System類介紹及常用方法&#xff08;了解知道即可&#xff09; Runtime類介紹及常用方法&#xff08;了解知道即可&#xff09; 代碼&#xff1a; 代碼一&#xff1a;Math類 package com.itheima.d14_math;public …