套接字(Socket),是 C++/C 做网络编程的核心,是实现两台电脑之间通过网络通信的入口,也是从纯语法学习过渡到实际开发的关键知识点。
套接字(Socket)是网络通信中用于不同主机间进程通信的端点,它封装了 IP 地址和端口号,提供了应用程序与网络协议栈之间的接口,使进程能够通过网络发送和接收数据。
本文介绍了 C++ 网络编程的核心组件套接字(Socket)。内容涵盖 Socket 的定义与生活化类比(如打电话),解释其在 C++ 中本质为整型描述符。详细阐述了 Socket 的三大核心要素(协议族、通信类型、IP 端口),对比了 TCP 与 UDP 的区别,并展示了服务端与客户端的极简核心流程代码。旨在帮助开发者理解底层网络细节封装及 API 调用方法。

套接字(Socket),是 C++/C 做网络编程的核心,是实现两台电脑之间通过网络通信的入口,也是从纯语法学习过渡到实际开发的关键知识点。
套接字(Socket)是网络通信中用于不同主机间进程通信的端点,它封装了 IP 地址和端口号,提供了应用程序与网络协议栈之间的接口,使进程能够通过网络发送和接收数据。
套接字 = 网络中两台设备(电脑/服务器)之间,进行数据通信的唯一接口/唯一标识
白话翻译:套接字就是网络通信里的「通信管道的总阀门」,你所有要发送/接收的网络数据,都必须经过这个「阀门」;没有套接字,你的程序就无法和网络中的任何其他程序通信。
这是理解套接字最经典、最准确的类比,所有 Socket 的核心概念都能对应上:
网络通信 = 两个人打一通电话
192.168.1.100) → 作用:定位网络中的某一台设备80/8080/3306) → 作用:定位一台设备上的某一个程序(一台电脑会运行 QQ、浏览器、微信等多个需要网络的程序,端口号用来区分它们)套接字 ≠ IP 地址,套接字 ≠ 端口号 套接字 = IP 地址 + 端口号 + 通信协议 (TCP/UDP) 的「三位一体绑定体」 缺了任何一个,都不能成为有效的 Socket,也无法通信。
套接字 (Socket) 是操作系统内核提供的一种「网络通信的内核对象」,是操作系统为程序员封装的网络编程接口 (API),它把复杂的底层网络协议 (TCP/IP)、网卡数据传输、二进制数据封装等细节全部隐藏起来,程序员只需要调用操作系统提供的 Socket 相关函数,就能轻松实现「跨设备的网络数据收发」。
你写的 C++ 程序,本质是运行在「应用层」的,而网络数据的传输是在「传输层/网络层」完成的(比如 TCP/IP 协议),这两层之间是隔绝的。Socket 就是连接「应用层的 C++ 程序」和「底层网络协议」的桥梁:
socket()、send()、recv() 这些函数,操作系统会帮你处理所有底层细节;这和你学的文件操作是一个逻辑:你不用懂硬盘的磁道、扇区,只需要调用 open()、read()、write() 就能操作文件,Socket 就是「网络文件」的操作接口。
// 这就是 C++ 里定义一个套接字的代码,没有任何复杂语法!
int sockfd; // sockfd = socket file descriptor,就是套接字的变量名
在操作系统中,一切皆文件:
int fd = open("test.txt", O_RDWR); → fd 是文件描述符,是一个 int,后续的 read(fd)/write(fd) 都用这个 int 操作文件;int sockfd = socket(AF_INET, SOCK_STREAM, 0); → sockfd 是套接字描述符,也是一个 int,后续的 send(sockfd)/recv(sockfd) 都用这个 int 操作网络通信;✅ 本质相通:操作系统把「本地文件」和「网络连接」都当成「可读写的资源」,用整型数字来标识每一个资源,这个数字就是「句柄/描述符」。
fd 操作 → 读写本地文件;sockfd 操作 → 读写网络数据;你之前学的所有 int 变量的知识、指针的知识,完全能直接套用在 Socket 上,这就是 C++ 的设计精妙之处!
所有有效的 Socket,都必须包含这三个核心要素,这是网络通信的基础,也是你写代码时必须设置的内容,缺一不可:
AF_INET表示你要使用的网络地址类型,开发中 99% 的场景都用 AF_INET,它表示「IPv4 协议」,也就是我们日常上网的 IP 地址(比如 192.168.1.1、114.114.114.114)。
补充:
AF_INET6是 IPv6 协议,是未来的趋势,用法和 IPv4 一致。
这是 Socket 的核心分类,决定了你的程序用「哪种方式」通信,C++ 里通过函数参数指定,二选一:
SOCK_STREAM → 对应 TCP 协议SOCK_DGRAM → 对应 UDP 协议这是 Socket 的核心标识,就是我们之前电话类比里的「手机号 + 分机号」:
192.168.1.100,服务器的 IP 是 47.98.158.12;80 是 HTTP 网页、443 是 HTTPS 加密网页、3306 是 MySQL 数据库;8080、9090。✅ 核心规则:一台电脑上,同一个端口号,只能被一个程序占用。比如你的电脑上,80 端口被浏览器占用了,其他程序就不能再用 80 端口了。
不用记完整代码,只需要记住核心步骤,就能理解 Socket 在代码里是怎么用的,所有步骤都围绕「那个 int 类型的套接字描述符 sockfd」展开。
TCP 通信分为服务端(比如网站服务器、游戏服务器)和客户端(比如你的浏览器、游戏客户端),二者的流程不同,但核心都是操作 Socket。
#include <sys/socket.h> // Socket 核心头文件
#include <netinet/in.h> // IP/端口相关头文件
int main() {
// 1. 创建套接字 → 得到一个 int 类型的套接字描述符
int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP 流式套接字
// 2. 绑定 IP+端口 → 给这个 Socket 绑定标识,让客户端能找到自己
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080); // 自定义端口号 8080
addr.sin_addr.s_addr = INADDR_ANY; // 绑定本机所有 IP
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
// 3. 监听连接 → 开启"接听电话"模式,等待客户端连接
listen(sockfd, 10);
// 4. 接受连接 → 接到电话,建立通信管道,得到新的 Socket 描述符
int connfd = accept(sockfd, NULL, NULL);
// 5. 收发数据 → 核心操作,用 send/recv 读写网络数据,和 read/write 文件一样
char buf[1024] = "Hello 客户端!";
send(connfd, buf, sizeof(buf), 0); // 发送数据
recv(connfd, buf, sizeof(buf), 0); // 接收数据
// 6. 关闭套接字 → 挂电话,释放资源
close(connfd);
close(sockfd);
return 0;
}
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
// 1. 创建套接字 → 同样得到 int 类型的套接字描述符
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 2. 指定服务端的 IP+端口 → 知道要"打给谁的电话"
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080); // 服务端的端口
server_addr.sin_addr.s_addr = inet_addr("192.168.1.100"); // 服务端的 IP
// 3. 连接服务端 → 拨打电话,建立连接
connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
// 4. 收发数据 → 和服务端互相通信
char buf[1024];
recv(sockfd, buf, sizeof(buf), 0); // 接收服务端数据
send(sockfd, "Hello 服务端!", 12, 0); // 发送数据
// 5. 关闭套接字 → 挂电话
close(sockfd);
return 0;
}
int,就是套接字描述符,和你学的 open() 返回值一致;bind 函数里的 &addr 是取地址符,就是你之前学的 & 的第一个用法,把结构体的地址传给函数;char 数组的操作,就是你学的 C++ 字符数组,没有任何新语法。你现在的 C++ 知识,已经能看懂所有 Socket 核心代码了!
Socket 的英文原意是:插座、插孔、接口。这个翻译是信达雅的完美典范:
int 整型变量,叫套接字描述符,和文件描述符同源,用法类似;
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online