【网络】TCP通信建立过程(图文解析)------------三次握手

TCP协议简介

TCP:Transmission Control Protocol 传输控制协议
TCP的三个特性:面向连接、可靠传输、面向字节流

TCP建立通信流程

与DUP的通信流程不同,TCP与其特性对应,通信流程较为复杂,如下图所示
在这里插入图片描述1.创建套接字:调用socket函数创建文件描述符;
接口:int socket( int domain, int type, int protocol );
domain:地址域类型
type:套接字类型
protocol:协议类型

2.绑定地址:调用bind函数将当前的文件描述符和ip/port绑定在一起。如果这个端口已经被其他进程占用了,就会绑定失败。
接口: int bind( int socket, const struct sockaddr *addr, socklen_t address_len );
socker:套接字描述符
addr:地址信息
address_len:地址信息长度

3.开始监听:调用listen函数,声明套接字处于监听状态,若有新连接到来,链接建立成功后,就会创建一个新的套接字来与这个客户端进行联系。
接口: int listen( int sockfd, int backlog);
sockfd:套接字描述符
backlog: 是未经过处理的连接请求队列可以容纳的最大数目(最大并发连接数)
监听状态下,内核为任何一个给定的监听套接口维护两个队列:
未完成连接队列(未完成三次握手队列):服务器正在等待完成相应的TCP三路握手过程,队列中套接口处于SYN_RCVD状态;
已完成连接队列(已经完成三次握手队列):已完成TCP三路握手过程的客户端对应其中一项,这些套接口都处于ESTABLISHED状态。
当队列中的连接数达到backlog个后,系统收到syn将不再回复syn+ack

4.新建连接:调用accept函数阻塞等待客户端连接到来。
接口:Int accept( int sockfd; struct sockaddr *addr, socklen_t *addrlen);
sockfd:套接字描述符,指获取哪个监听套接字新建的连接
addr:客户端的地址信息
addrlen:地址信息长度

5.发送连接请求
接口:int connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
客户器端收到SYN+ACK后会从connect函数中返回,同时应答一个ACK段

<think>嗯,用户这次想详细了解TCP三次握手过程和作用。从问题来看,用户应该具备基础的网络知识,但可能对协议细节不太熟悉。我注意到用户主动提供了两个站内引用,说明ta已经做过一些资料收集,需要的是系统化的讲解。我准备从七个维度展开回答:握手步骤的图文解析、状态变化、随机序列号的作用、队列机制、攻击防护、P2P应用的例外情况,以及核心的“为什么需要三次握手”这个经典问题。在状态描述中需要特别注意区分客户端和服务端的视角变化。考虑到协议交互的抽象性,会搭配分段图示(ASCII风格)来帮助理解,比如用两个竖排的竖线字符来模拟两台主机,用带箭头的横线标出传输方向。每次传输必须强调SEQ和ACK的具体数值变化,这是用户最容易混淆的点。对于“作用”部分,除了基础的连接可靠性,还要突出全双工通信的特性建立过程。准备用$$...$$格式呈现关键公式:$NextExpectedSeq=LastReceivedSeq+DataLength$,这样能直观展示序列号跟踪机制。用户可能会追问“两次握手为什么不够”,这需要从信道不可靠性和历史连接干扰两个层面解释。另外,如果涉及Linux的实现细节,比如半连接队列的/proc参数,也要提前准备补充点。最后考虑生成的问题链:从基础流程到异常处理,再到内核实现和优化方案,这样用户可以按需深入。特别要注意标注引用来源,比如SYNcookie的RFC编号[^1]。</think> ### TCP三次握手详解 --- #### **一、三次握手过程图解(客户端A ↔ 服务端B)** ``` A (客户端) B (服务端) 1. SYN_SENT → SYN=1, seq=x → SYN_RCVD (主动打开连接) 2. ESTABLISHED ← SYN=1, ACK=1, seq=y, ack=x+1 ← (确认收到SYN) 3. → ACK=1, seq=x+1, ack=y+1 → ESTABLISHED (确认收到SYN+ACK) ``` #### **二、核心作用** 1. **同步初始序列号** 双方通过交换随机生成的初始序列号 `seq`(如$x$和$y$)建立数据包排序基准,确保数据按序传输。 2. **双向信道可靠性验证** 通过 $A\rightarrow B$(SYN)、$B\rightarrow A$(SYN+ACK)、$A\rightarrow B$(ACK)三次交互,**双向确认通信能力**,防止失效求占用资源。 3. **协商关键参数** 交换MSS(最大报文段长度)、窗口缩放因子等参数,为后续传输优化做准备。 --- #### **三、握手状态详解** | **状态** | **触发方** | **含义** | |----------------|------------|--------------------------------------------------------------------------| | `SYN_SENT` | 客户端 | 发送SYN后等待服务端响应 | | `SYN_RCVD` | 服务端 | 收到SYN并回复SYN+ACK后,等待最终ACK | | `ESTABLISHED` | 双方 | 收到对端确认包,连接正式建立 | --- #### **四、关键技术机制** 1. **队列管理** - **半连接队列(SYN队列)**:存储`SYN_RCVD`状态的- **全连接队列(Accept队列)**:存储完成握手待`accept()`的连接 ```bash # Linux查看队列大小 ss -lnt 'sport = :80' ``` 2. **防御SYN泛洪攻击** - **SYN Cookie技术**:服务端不存储SYN_RCVD状态,通过加密算法验证ACK有效性 - 队列扩容:调节 `/proc/sys/net/ipv4/tcp_max_syn_backlog` 3. **随机序列号意义** - 避免历史连接混淆(重复序列号导致数据错乱) - 防止网络预测攻击(如IP欺骗)[^1] --- #### **五、经典问题解答** > **为什么需要三次而非两次?** > 关键原因:**防止失效连接求突然到达**。 > 假设场景: > - 旧SYN(seq=123)因网络延迟滞留 > - 若两次握手,服务端收到旧SYN直接进入`ESTABLISHED`,但客户端已放弃连接 > **结果**:服务端资源被无效占用 > **三次握手**:客户端拒绝非预期ACK(需验证$y$值),避免虚假连接[^2] --- #### **六、特殊场景:P2P穿透** 在NAT环境中实现P2P直连时: 1. 双方同时发送SYN(行为类似SYN_SENT状态) 2. 利用STUN服务器交换公网地址 3. NAT设备自动转换地址 > 此场景绕过了传统三次握手序列(详见ICE协议)[^1] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值