C++网络编程:从套接字到异步

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++网络编程:从套接字到异步

\n\n

您是否曾思考过聊天软件、在线游戏或Web服务器是如何工作的?它们的基础都是网络通信。如果您想编写快速、可靠且底层的网络应用程序,C++网络编程正是您所需要的。本文不仅会讲解理论,还会编写真正的代码:从简单的TCP聊天程序到使用Boost.Asio的异步服务器。准备好您的IDE——这将非常有趣!

\n\n

为什么选择C++进行网络编程?三个理由

\n

许多人选择Python或Java来处理网络任务,但C++提供了三个关键优势:

\n
    \n
  • 速度:最小的开销,直接访问系统调用(syscalls)。
  • \n
  • 控制:您可以手动管理内存、缓冲区和时间。
  • \n
  • 生态系统:Boost.Asio、libcurl、Poco——适用于任何任务的强大库。
  • \n
\n

但能力越大,责任越大:套接字管理中的一个错误就可能导致服务器崩溃。让我们来了解如何避免这种情况。

\n\n

基础:套接字与OSI模型

\n

在编写代码之前,我们先回顾一下什么是套接字。它是一种抽象,允许应用程序通过网络发送和接收数据。在C++中,我们通过sys/socket.h(Linux)或winsock2.h(Windows)来操作。

\n\n

TCP vs UDP:何时使用哪种?

\n
    \n
  • TCP(SOCK_STREAM):保证数据送达和包顺序。非常适合聊天、HTTP、数据库。
  • \n
  • UDP(SOCK_DGRAM):速度更快,但无保证。用于流媒体、DNS、在线游戏(丢包比延迟更容易承受)。
  • \n
\n\n

用C++编写TCP服务器和客户端(纯套接字)

\n

让我们创建一个最简单的回显服务器。它接收消息并将其发送回去。这是网络编程中的经典“Hello, World”。

\n\n

服务器端(echo_server.cpp)

\n
#include <iostream>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <unistd.h>\n#include <cstring>\n\nint main() {\n    int server_fd, client_fd;\n    struct sockaddr_in address;\n    int opt = 1;\n    int addrlen = sizeof(address);\n    char buffer[1024] = {0};\n\n    // 1. 创建套接字\n    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {\n        perror("socket failed");\n        exit(EXIT_FAILURE);\n    }\n\n    // 2. 绑定到端口(重用端口选项)\n    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {\n        perror("setsockopt");\n        exit(EXIT_FAILURE);\n    }\n    address.sin_family = AF_INET;\n    address.sin_addr.s_addr = INADDR_ANY;\n    address.sin_port = htons(8080);\n\n    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {\n        perror("bind failed");\n        exit(EXIT_FAILURE);\n    }\n\n    // 3. 监听传入连接\n    if (listen(server_fd, 3) < 0) {\n        perror("listen");\n        exit(EXIT_FAILURE);\n    }\n\n    std::cout << "服务器已在端口8080启动。等待连接..." << std::endl;\n\n    // 4. 接受客户端\n    if ((client_fd = accept(server_fd, (struct sockaddr *)&address,\n                            (socklen_t*)&addrlen)) < 0) {\n        perror("accept");\n        exit(EXIT_FAILURE);\n    }\n\n    // 5. 读取并发送回(回显)\n    int valread = read(client_fd, buffer, 1024);\n    std::cout << "收到: " << buffer << std::endl;\n    send(client_fd, buffer, strlen(buffer), 0);\n    std::cout << "回显响应已发送" << std::endl;\n\n    close(client_fd);\n    close(server_fd);\n    return 0;\n}
\n\n

客户端部分(echo_client.cpp)

\n
#include <                

博客

书籍推荐