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.mzph.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 …