TCP 传输控制协议

一、网络架构模型

1. CS 模型(Client-Server,客户端 - 服务器)

  • 定义:专用客户端与服务器交互的模型,客户端为定制化程序,服务器提供核心服务。
  • 典型场景:即时通讯软件、游戏客户端、本地工具类程序。

2. BS 模型(Browser-Server,浏览器 - 服务器)

  • 定义:以通用浏览器作为客户端,服务器通过 Web 服务提供内容。
  • 典型场景:网页版应用、电商网站、在线文档。

3. P2P 模型(Peer-to-Peer,对等网络)

  • 定义:无中心服务器,节点既是客户端(下载者)也是服务器(上传者)。
  • 核心特征
    • 初始阶段:节点从其他客户端 / 服务器下载数据(进度 0%);
    • 后期阶段:节点完成部分下载后,向新节点上传已获取的数据;
    • 典型场景:迅雷、BT 下载等 P2P 网络下载工具。

4. CS vs BS 核心区别

维度 CS 模型 BS 模型
客户端类型 专用客户端(定制开发) 通用浏览器(无需定制)
应用层协议 自定义 / 标准协议均可 固定使用 HTTP/HTTPS 协议
功能复杂度 功能丰富、逻辑复杂 功能轻量化、逻辑简单
资源存储 部分资源本地化存储 核心资源由服务器分发

二、TCP 协议核心特征

TCP(Transmission Control Protocol,传输控制协议)是面向连接的可靠传输协议,核心特征如下:

1. 核心特性

特性 说明
面向连接 通信前需完成三次握手 建立连接,断开需四次挥手,连接始终保持至主动断开
可靠传输 通过应答(ACK)、超时重传保证数据不丢失、不重复、按序到达
流式套接字 数据无边界,为连续字节流,接收方无法直接区分单次发送的数据块
全双工通信 两端均有发送 / 接收缓冲区,可同时收发数据
收发次数无关 发送方多次发送的数据,接收方可一次性读取(黏包问题根源)
写阻塞机制 发送缓冲区满时(默认 64K),send 函数会阻塞,直至缓冲区有空闲空间
连接感知 一端断开连接,另一端可通过 recv 返回 0 / 错误感知,基于四次挥手保证优雅断开

2. 可靠传输实现机制

  • 应答机制(ACK):接收方收到数据后返回 ACK 确认,发送方收到 ACK 才认为数据传输成功;
  • 超时重传:发送方未在指定时间收到 ACK,自动重传数据;
  • 实时性弱:为保证可靠性,牺牲部分实时性(对比 UDP);
  • 资源消耗:头部开销大、连接建立 / 断开需握手,网络资源消耗高于 UDP。

3. 黏包问题

  • 定义:TCP 数据无边界,发送方多次发送的小数据块可能被合并传输,接收方一次性读取后无法还原原始数据块,导致解析失败。
  • 根源:流式套接字特性 + 内核缓冲区优化(Nagle 算法)。
  • 解决思路:自定义数据边界(如固定长度、分隔符、头部标识长度)。

三、TCP 核心函数(Linux/C)

1. 创建套接字:socket ()

c

运行

复制代码
int socket(int domain, int type, int protocol);
  • 功能:向内核申请创建套接字,返回文件描述符(FD)。
  • 参数
    • domain:地址族,AF_INET(互联网协议,IPv4)/AF_UNIX(本地进程通信);
    • type:套接字类型,SOCK_STREAM(流式,TCP)/SOCK_DGRAM(数据报,UDP)/SOCK_RAW(原始套接字);
    • protocol:协议类型,0 表示自动适配 type 对应的默认协议。
  • 返回值:成功返回套接字 FD,失败返回 - 1。

2. 绑定地址:bind ()

c

运行

复制代码
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
  • 功能:将套接字 FD 与指定 IP + 端口绑定(服务器专用)。
  • 参数
    • sockfd:socket () 返回的套接字 FD;
    • my_addr:存储本机 IP、端口的地址结构体(struct sockaddr_in);
    • addrlen:地址结构体的长度(sizeof (struct sockaddr_in))。
  • 返回值:成功返回 0,失败返回 - 1。

3. 监听连接:listen ()

c

运行

复制代码
int listen(int sockfd, int backlog);
  • 功能:将套接字转为监听状态,等待客户端连接(服务器专用)。
  • 参数
    • sockfd:绑定后的套接字 FD;
    • backlog:三次握手队列的最大长度(未完成连接队列 + 已完成连接队列)。
  • 返回值:成功返回 0,失败返回 - 1。

4. 接受连接:accept ()

c

运行

复制代码
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • 功能:从监听队列取出已建立的客户端连接,创建通信套接字(服务器专用)。
  • 参数
    • sockfd:监听套接字 FD;
    • addr:输出参数,存储客户端的 IP + 端口(NULL 表示不关心);
    • addrlen:输入输出参数,传入 addr 的长度,返回实际长度(addr 为 NULL 时设为 NULL)。
  • 核心说明
    • 监听套接字(sockfd):仅负责监听,不参与通信;
    • 通信套接字(返回值):专用于与该客户端的收发数据。
  • 返回值:成功返回通信套接字 FD,失败返回 - 1。

5. 接收数据:recv ()

c

运行

复制代码
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • 功能:从套接字读取数据到本地缓冲区。
  • 参数
    • sockfd:服务器用 accept () 返回的通信 FD,客户端用 socket () 返回的 FD;
    • buf:存储数据的缓冲区(数组 / 动态内存);
    • len:期望读取的字节数;
    • flags:读取方式,0 表示阻塞读取。
  • 返回值:成功返回实际读取的字节数,失败返回 - 1,对端断开返回 0。

6. 发送数据:send ()

c

运行

复制代码
ssize_t send(int sockfd, const void *msg, size_t len, int flags);
  • 功能:将缓冲区数据写入套接字发送给对端。
  • 参数
    • sockfd:同 recv () 的 sockfd 规则;
    • msg:待发送的数据缓冲区;
    • len:待发送的数据长度;
    • flags:发送方式,0 表示阻塞发送。
  • 返回值:成功返回实际发送的字节数,失败返回 - 1。

7. 发起连接:connect ()

c

运行

复制代码
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 功能:客户端向服务器发起 TCP 连接请求(客户端专用)。
  • 参数
    • sockfd:socket () 返回的客户端套接字 FD;
    • addr:服务器的 IP + 端口地址结构体;
    • addrlen:地址结构体长度。
  • 返回值:成功返回 0,失败返回 - 1。

四、TCP 编程调用流程

1. 服务器端

plaintext

复制代码
socket() → bind() → listen() → accept() → recv()/send() → close()
  • 核心:先绑定监听端口,再接受连接,最后通过通信套接字收发数据。

2. 客户端

plaintext

复制代码
socket() → connect() → send()/recv() → close()
  • 核心:无需绑定端口(系统自动分配),直接连接服务器后收发数据。

五、补充:桥接设置(局域网通信)

  • 定义:创建虚拟网络设备,将本地网络接口与局域网设备直连;
  • 目的:实现同一教室 / 局域网内的设备互通,便于 CS 程序调试。

总结

TCP 作为可靠的面向连接协议,是 CS/BS 模型的核心基础,掌握其核心特性、函数用法和编程流程,是网络开发的必备技能。重点需关注:

  1. 三次握手 / 四次挥手的连接机制;
  2. 监听套接字与通信套接字的区别;
  3. 黏包问题的产生与解决;
  4. CS/BS/P2P 模型的适用场景。
相关推荐
新时代牛马5 小时前
Linux 磁盘管理:分区、文件系统、挂载与扩容
linux·运维·服务器
weixin_402486345 小时前
VS Code Codex/Claude Extension 无法安装 / 无法正常打开
linux·服务器·vscode
流烟默5 小时前
HTTP 连接管理技术梳理:JDK KeepAliveCache 机制与池化选型
java·网络协议·http
大树885 小时前
液冷系统的真正瓶颈,藏在那层不到1毫米的材料里
大数据·运维·服务器·人工智能·ai
深念Y5 小时前
iOS模拟器在无Metal的NVIDIA显卡环境下的可行性研究报告
服务器·ios·unix·pve·freebsd
Java小白笔记6 小时前
FlClash TUN 栈模式选择与验证指南
网络·网络协议
网硕互联的小客服6 小时前
没有公网IP,如何让外网访问内网服务器?
运维·服务器
布裘6 小时前
【银河麒麟】服务器系统开机黑屏故障排查与修复
linux·运维·服务器·银河麒麟·无法启动
Zenova EdgeOS6 小时前
Linux iotop:工业边缘 I/O 高级分析实战
linux·运维·服务器
清水白石0086 小时前
ThreadPoolExecutor 线程越多越快?从 30ms HTTP 调用讲透并发数、连接池与背压
网络·网络协议·http