当前位置: 首页 > article >正文

【C++网络编程】第1篇:网络编程基础概念

工具/C++库安装相关

注意:复现代码时,确保 VS2022 使用 C++17/20 标准以支持现代特性。


一、网络模型核心:OSI与TCP/IP

1. OSI七层模型

  • 分层结构:物理层 → 数据链路层 → 网络层 → 传输层 → 会话层 → 表示层 → 应用层
  • 核心作用:标准化网络通信流程,各层独立工作(如传输层负责端到端连接,网络层处理IP寻址)。

2. TCP/IP四层模型

​实际应用模型:

应用层(HTTP/FTP)  
↓  
传输层(TCP/UDP)  
↓  
网络层(IP/ICMP)  
↓  
网络接口层(以太网/Wi-Fi)  
  • 与OSI对比:TCP/IP更贴近实际协议(如HTTP基于TCP,DNS基于UDP)。

二、Socket编程基础

1. 什么是Socket?

定义:操作系统提供的网络通信接口,可视为“网络文件描述符”。
通信要素

  • IP地址:标识设备(IPv4如192.168.1.1,IPv6如2001:db8::1)。
  • 端口号:标识应用程序(0-65535,其中0-1023为系统保留)。
  • 协议类型:TCP(可靠连接)或 UDP(无连接)。

2. Socket通信流程(TCP)

  • 服务器端
socket() → bind() → listen() → accept() → recv()/send() → close()
  • ​客户端
socket() → connect() → send()/recv() → close()

三、Winsock库入门

1. 初始化与清理

  • WSAStartup():初始化Winsock库,必须调用。
  • WSACleanup():清理资源,程序退出前调用。
  • 代码示例
#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")  // 自动链接Winsock库

int main() {
    // 1. 初始化Winsock
    WSADATA wsaData;
    int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        std::cerr << "WSAStartup failed: " << result << std::endl;
        return 1;
    }

    // 2. 检查版本号
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        std::cerr << "Winsock 2.2 not supported!" << std::endl;
        WSACleanup();
        return 1;
    }

    std::cout << "Winsock initialized successfully!" << std::endl;

    // 3. 清理Winsock
    WSACleanup();
    return 0;
}

2. 关键数据结构

  • sockaddr_in:存储IPv4地址和端口。
struct sockaddr_in {
    short          sin_family;  // 地址族(AF_INET)
    u_short        sin_port;    // 端口号(网络字节序)
    struct in_addr sin_addr;    // IP地址
    char           sin_zero[8]; // 填充
};
  • in_addr:32位IPv4地址。
struct in_addr {
    union {
        struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;
        struct { u_short s_w1, s_w2; } S_un_w;
        u_long S_addr;  // 常用(如inet_addr("127.0.0.1"))
    } S_un;
};

四、实战:解析IP与端口

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h> 
#pragma comment(lib, "ws2_32.lib")  // 自动链接Winsock库

#include <ctype.h>
#include <limits.h>


int main() {
    // 1. 初始化Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup failed!" << std::endl;
        return 1;
    }

    // 2. 创建Socket
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    // 3. 绑定地址和端口
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    inet_pton(AF_INET,"127.0.0.1", &(serverAddr.sin_addr.s_addr));  // 本地回环地址
    serverAddr.sin_port = htons(8080);                    // 监听8080端口

    if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Bind failed: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    // 4. 开始监听
    if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
        std::cerr << "Listen failed: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Server started. Listening on 127.0.0.1:8080..." << std::endl;
    
    // 5. 清理资源
    closesocket(serverSocket);
    WSACleanup();
    return 0;
}

五、常见错误与调试

1. 错误码获取

  • WSAGetLastError():获取最后一次Winsock错误。
    // 接受客户端连接
    sockaddr_in clientAddr;
    int clientAddrLen = sizeof(clientAddr);
    SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrLen);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Accept failed: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

2. 典型错误码

错误码含义
WSAEADDRINUSE端口已被占用
WSAECONNREFUSED连接被拒绝(目标未监听)
WSAETIMEDOUT连接超时

http://www.kler.cn/a/594126.html

相关文章:

  • 多维array和多维视图std::mdspan
  • Android自动化测试终极指南:从单元到性能全覆盖!
  • 【QA】Qt中直接渲染和离屏渲染效率哪个高?
  • ZYNQ14 基于正点原子的iic时序的fpga程序实现
  • 一学就会:A*算法详细介绍(Python)
  • springboot+mysql增删改查
  • Java、Python、PHP、Go:网站开发语言全维度对比与选择指南
  • win10 c++ VsCode 配置PCL open3d并显示
  • 源代码防泄密和安全上外网的关联
  • 第一个Spring程序基于Spring6
  • 使用C#创建安装Windows服务程序
  • 蓝桥杯十天冲刺-day1(日期问题)
  • 软考笔记——程序设计语言基础知识
  • Git 回退操作详解:带示例的“小白”指南
  • 编译构建google R8源码
  • 谈谈最近AI在我工作生活中的深度应用
  • JVM常用概念之对象对齐
  • Linux目录操作学习总结
  • squirrel语言全面介绍
  • LeetCode[242]有效的字母异位词