2、网络基础:TCP/IP协议栈回顾、Socket编程基础、局域网通信原理
做多屏互动,说白了就是让几块屏幕在局域网里互相"说话"。你想想看,手机投屏到电视、电脑扩展第二块显示器、会议室里多屏拼接——这些场景背后,都离不开网络通信。
我刚开始做这个项目时,觉得网络通信嘛,调个接口就行了。结果第一次联调,画面卡成PPT,声音断断续续。后来才发现,问题出在最基础的TCP/IP协议理解上。嗯,这一章我们就来把地基打牢。
2.1 TCP/IP协议栈——数据是怎么"打包"的?
先看一张整体图,帮你建立全局认知:
这张图我建议你多看两眼。每次数据从你的App发出,都要经过这四层"打包"。反过来,接收端要一层层"拆包"。
2.2 传输层选型:TCP vs UDP
做多屏互动,第一个要做的决定就是:用TCP还是UDP?
我见过不少新手,上来就用TCP,觉得可靠。结果画面延迟高得离谱。也见过有人全用UDP,结果丢包丢到画面花屏。
| 对比维度 | TCP | UDP |
|---|---|---|
| 连接方式 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 保证送达,自动重传 | 不保证送达,可能丢包 |
| 数据顺序 | 保证有序 | 不保证有序 |
| 传输延迟 | 较高(重传机制) | 低(无重传) |
| 适用场景 | 控制指令、文件同步 | 音视频画面、实时数据 |
实战经验:我在做多屏同步时,采用"双通道"策略——控制信令走TCP,画面数据走UDP。这样既保证了指令的可靠性,又保证了画面的实时性。
2.3 Socket编程基础——让设备"开口说话"
Socket,说白了就是网络通信的"门"。你要跟另一台设备通信,就得先打开这扇门。
我习惯把Socket通信比作打电话:
- 服务端:先装好电话(bind),然后等着(listen),有人打进来就接(accept)
- 客户端:直接拨号(connect),接通后说话(send/recv)
- 挂断:说完就挂(close)
来看一个最简的TCP服务端代码:
// TCP服务端 - 多屏互动控制信令接收
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int server_fd, client_fd;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
// 1. 创建Socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
// 2. 绑定端口(我习惯用 8080 做控制端口)
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
// 3. 监听,最大等待队列设为3
listen(server_fd, 3);
printf("多屏控制服务已启动,等待设备连接...\n");
// 4. 接受客户端连接
client_fd = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen);
// 5. 接收数据
read(client_fd, buffer, 1024);
printf("收到指令: %s\n", buffer);
// 6. 关闭连接
close(client_fd);
close(server_fd);
return 0;
}
小技巧:调试时可以用 telnet 192.168.1.100 8080 模拟客户端发数据,不用每次都写客户端代码。
2.4 局域网通信原理——设备怎么"找到"彼此?
多屏互动通常都在同一个局域网里。设备之间怎么发现对方?
主要有三种方式:
- 手动指定IP:最简单,但不够灵活。适合固定场景。
- 广播/UDP组播:设备启动时发个广播包,告诉全网"我在这里"。其他设备收到后,就知道它的IP和端口了。
- mDNS/DNS-SD:苹果的Bonjour用的就是这个。设备注册一个名字,比如"客厅电视.local",其他设备直接通过名字访问。
我个人最推荐第二种——UDP广播发现。原因很简单:实现起来不复杂,而且兼容性好。
曾经踩过的坑:有一次我在做多屏发现功能,广播包发出去,部分设备收不到。查了半天,发现是路由器的"广播隔离"功能开了。嗯,企业级路由器默认会隔离广播域,记得关掉或者改用组播。
2.5 局域网通信的"坑"与对策
做多屏互动,局域网环境看着简单,实际坑不少。我列几个常见的:
| 问题 | 现象 | 对策 |
|---|---|---|
| Wi-Fi延迟抖动 | 画面忽快忽慢 | 使用UDP + 抖动缓冲(jitter buffer) |
| 多设备同时发送 | 数据碰撞、丢包 | 引入简单的"令牌"机制,轮流发送 |
| 设备IP变化 | 连接突然断开 | 心跳检测 + 自动重连 |
| 防火墙拦截 | Socket连接失败 | 使用常见端口(如8080、9090)或提示用户放行 |
我的经验:做多屏互动,一定要在代码里加"心跳包"。每1秒发一个很小的UDP包,告诉对方"我还活着"。连续3次没收到,就判定设备离线,触发重连逻辑。这个机制救了我好几次。
2.6 本章小结
这一章我们聊了TCP/IP协议栈的四层结构,TCP和UDP怎么选,Socket编程的基本套路,以及局域网设备发现和通信的常见问题。
说白了,多屏互动的网络基础就三件事:选对协议、写好Socket、处理好局域网的特殊性。把这些搞明白了,后面写代码心里就有底了。