Visual C++ 网络编程教程
目录
- 准备工作:开发环境配置
- 第一部分:网络编程基础概念
- 1 OSI 七层模型与 TCP/IP 四层模型
- 2 IP 地址、端口号与套接字
- 3 两种主要的传输协议:TCP 与 UDP
- 第二部分:Windows Sockets (Winsock) 编程
- 1 什么是 Winsock?
- 2 Winsock 编程基本流程
- 第三部分:实战项目一 - 基于 TCP 的简单聊天程序
- 1 项目目标
- 2 服务器端实现
- 3 客户端实现
- 4 编译与运行
- 第四部分:实战项目二 - 基于 UDP 的数据回显程序
- 1 项目目标
- 2 服务器端实现
- 3 客户端实现
- 4 编译与运行
- 第五部分:进阶与资源
- 1 阻塞 vs. 非阻塞模式
- 2 Winsock I/O 模型(选择、重叠、完成端口)
- 3 推荐书籍与在线资源
准备工作:开发环境配置
在开始之前,请确保你的电脑上已安装 Visual Studio,我们推荐使用 Visual Studio 2025 或更高版本,它们对 C++17/C++20 有更好的支持。

创建新项目步骤:
- 打开 Visual Studio。
- 选择 “创建新项目” (Create a new project)。
- 在搜索框中输入
空项目(Empty Project) 或Windows Desktop Application,选择它并点击 “下一步”。 - 为项目命名(
WinsockDemo),选择位置,然后点击 “创建”。 - 在右侧的 “解决方案资源管理器” 中,右键点击 “源文件” -> “添加” -> “新建项”。
- 选择
C++ 文件 (.cpp),命名为main.cpp,然后点击 “添加”。
一个可以编写 C++ 代码的空白项目就准备好了。
第一部分:网络编程基础概念
1 OSI 七层模型与 TCP/IP 四层模型
网络通信是一个非常复杂的过程,为了标准化,人们设计了分层模型,最著名的是 OSI 七层模型,但实际应用中我们更常接触的是 TCP/IP 四层模型。
| TCP/IP 四层模型 | OSI 七层模型 | 主要功能与协议示例 |
|---|---|---|
| 应用层 | 应用层 | 为应用程序提供服务 (HTTP, FTP, SMTP, DNS) |
| 表示层 | 数据格式转换、加密解密 | |
| 会话层 | 建立、管理和终止会话 | |
| 传输层 | 传输层 | 提供端到端的可靠或不可靠数据传输 (TCP, UDP) |
| 网络层 | 网络层 | 负责逻辑寻址和路由选择 (IP, ICMP) |
| 网络接口层 | 数据链路层 | 负责物理寻址和帧传输 (Ethernet, Wi-Fi) |
| 物理层 | 传输二进制比特流 (网线, 光纤, 电信号) |
作为开发者,我们主要工作在 应用层 和 传输层。

2 IP 地址、端口号与套接字
- IP 地址:如同你家房子的门牌地址,在网络中唯一标识一台主机。
168.1.100或8.8.8。 - 端口号:如同你家里的房间号,在一台主机上,不同的应用程序通过不同的端口号来区分,端口号是一个 16 位的整数,范围是 0-65535,0-1023 是熟知端口,通常被系统或标准服务占用(如 HTTP 80, FTP 21)。
- 套接字:这是网络编程的核心概念,你可以把它想象成一个“通信端点”,它包含了 IP 地址 + 端口号 的组合,应用程序通过创建和操作套接字来发送和接收网络数据。
3 两种主要的传输协议:TCP 与 UDP
| 特性 | TCP (Transmission Control Protocol) | UDP (User Datagram Protocol) |
|---|---|---|
| 连接性 | 面向连接 | 无连接 |
| 可靠性 | 可靠,通过确认、重传、排序等机制确保数据不丢失、不重复、按序到达。 | 不可靠,不保证数据一定能到达,不保证顺序。 |
| 速度 | 较慢 | 快,因为协议开销小,没有复杂的连接建立和确认过程。 |
| 资源占用 | 较高 | 较低 |
| 应用场景 | 要求可靠传输的场景,如网页浏览、文件传输、邮件、远程登录。 | 对实时性要求高、能容忍少量丢包的场景,如视频会议、在线游戏、DNS查询。 |
第二部分:Windows Sockets (Winsock) 编程
1 什么是 Winsock?
Winsock (Windows Sockets) 是 Windows 平台下的网络编程接口,它基于伯克利套接字,并增加了 Windows 特有的功能,它是所有 Windows 网络应用程序的基础。
2 Winsock 编程基本流程
无论是 TCP 还是 UDP,编程的基本步骤都遵循一个固定的模式。
TCP 流程 (服务器端):
- 初始化 Winsock (
WSAStartup) - 创建套接字 (
socket) - 绑定套接字 (
bind) - 将套接字与本地 IP 和端口绑定 - 监听连接 (
listen) - 将套接字设置为监听模式 - 接受连接 (
accept) - 阻塞等待客户端连接,返回一个新的通信套接字 - 收发数据 (
send/recv) - 关闭套接字 (
closesocket) - 清理 Winsock (
WSACleanup)
TCP 流程 (客户端):

- 初始化 Winsock (
WSAStartup) - 创建套接字 (
socket) - 连接服务器 (
connect) - 收发数据 (
send/recv) - 关闭套接字 (
closesocket) - 清理 Winsock (
WSACleanup)
UDP 流程 (服务器端/客户端):
- 初始化 Winsock (
WSAStartup) - 创建套接字 (
socket) - 绑定套接字 (
bind) - (服务器端必须绑定,客户端通常可以绑定也可以不绑定) - 收发数据 (
sendto/recvfrom) - 每次操作都需要指定对方的地址 - 关闭套接字 (
closesocket) - 清理 Winsock (
WSACleanup)
第三部分:实战项目一 - 基于 TCP 的简单聊天程序
我们将创建一个简单的控制台聊天程序,服务器端等待客户端连接,然后双方可以互相发送消息。
1 项目目标
- 服务器端:监听指定端口,接受一个客户端连接,并可以与该客户端双向收发消息。
- 客户端:连接到服务器,并可以与服务器双向收发消息。
2 服务器端实现
在 main.cpp 中编写以下代码:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
// 链接 Winsock2.lib
#pragma comment(lib, "ws2_32.lib")
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 512
int main() {
// 1. 初始化 Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
// 2. 创建监听套接字
struct addrinfo* result = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET; // IPv4
hints.ai 