网络基础回顾:TCP/IP协议栈、端口与套接字、NAT穿透原理、公网与内网地址
做远程控制,说白了就是两台机器之间互相传数据。但机器之间怎么找到对方?数据怎么打包?中间隔着路由器怎么打通?这些底层逻辑如果不清楚,后面写代码就是瞎蒙。
这一章我把四个最核心的概念串起来讲。都是老生常谈的东西,但我会结合远程控制场景,告诉你哪些地方容易踩坑。
2.1 TCP/IP协议栈:数据是怎么一层层包起来的
TCP/IP协议栈分四层:应用层、传输层、网络层、网络接口层。远程控制的数据从你电脑的鼠标点击开始,一路往下封装,最后变成比特流从网线发出去。
我刚开始做远程控制时,一直搞不懂为什么延迟那么高。后来抓包一看,原来是应用层把鼠标事件一条条发,没做批量合并。每一条都要走完整四层封装,能不慢吗?
| 层级 | 典型协议 | 远程控制中的角色 |
|---|---|---|
| 应用层 | HTTP / WebSocket / RTSP | 传输鼠标事件、屏幕画面、剪贴板内容 |
| 传输层 | TCP / UDP | 保证数据可靠到达(TCP)或低延迟传输(UDP) |
| 网络层 | IP | 寻址和路由,决定数据包从哪条路走 |
| 网络接口层 | 以太网 / Wi-Fi | 把数据变成电信号或无线电波发出去 |
2.2 端口与套接字:谁在跟谁说话
IP地址找到机器,端口找到机器上的进程。套接字(Socket)就是IP+端口组合,唯一标识一个通信端点。
举个例子:你电脑IP是192.168.1.10,远程控制服务端监听在5900端口。客户端连过来时,它的套接字就是192.168.1.10:5900。客户端自己也会随机分配一个端口,比如192.168.1.20:54321。
// 典型的TCP服务端套接字创建流程(C语言风格)
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(5900); // 远程控制端口
addr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡
int opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));
listen(server_fd, 5);
2.3 公网与内网地址:你在哪,我在哪
公网IP全球唯一,可以直接访问。内网IP(比如192.168.x.x、10.x.x.x、172.16.x.x)只能在局域网内部用。远程控制最大的难题就是:被控端在内网,控制端也在内网,两边怎么打通?
你想想看,你家路由器分配给你电脑的是192.168.1.5,这个地址在公网上根本不存在。外部的控制端想连你,连到谁?
| 地址类型 | 范围 | 远程控制中的问题 |
|---|---|---|
| 公网IP | 全球唯一 | 可以直接连,但IPv4资源稀缺,大部分家庭用户没有 |
| 内网IP | 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12 | 外部无法直接访问,需要NAT穿透或中转 |
| 回环地址 | 127.0.0.1 | 只在本机有效,用于本地调试 |
2.4 NAT穿透原理:翻墙的艺术
NAT(网络地址转换)是路由器干的事。它把内网IP+端口映射成公网IP+端口,这样内网机器才能访问互联网。但反过来,外网主动连内网机器,路由器默认会拒绝——因为它不知道这个连接该转发给谁。
NAT穿透的思路很简单:让内网机器先主动往外发一个包,路由器就会在NAT表里记下这个映射关系。这时候外网机器往这个映射地址发包,路由器就会转发给内网机器。
常见的NAT穿透方式有三种:
- UDP打洞:双方都先往一个公共服务器发UDP包,服务器告诉对方各自的公网地址,然后双方直接互发。成功率取决于NAT类型。
- TCP打洞:比UDP复杂,因为TCP有状态。需要用到TCP的TIME_WAIT复用技巧。
- 中继转发:打洞失败时,所有数据都经过一台公网服务器中转。延迟高,但最稳定。
为什么会打洞失败?因为有些NAT是“对称NAT”——每次同一个内网IP+端口发往不同目标,路由器都会分配不同的公网端口。这种NAT基本打不了洞,只能走中继。
2.5 端口映射:最朴素的穿透方式
如果NAT穿透搞不定,还有一个土办法——在路由器上手动配端口映射。把路由器的公网端口直接映射到内网机器的某个端口上。
比如在路由器管理页面设置:公网端口5900 → 内网192.168.1.20:5900。这样外网访问路由器公网IP的5900端口,就等于访问内网被控端的5900端口。
好了,这一章的基础概念就讲到这里。TCP/IP协议栈让你知道数据怎么封装,端口和套接字让你知道通信端点怎么标识,公网内网地址让你知道机器在哪,NAT穿透和端口映射让你知道怎么打通两边的路。这些是远程控制的底层骨架,后面所有章节都建立在这些概念之上。