详解TCP的三次握手

article/2025/10/14 10:09:08

TCP定义及特点

定义

TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,发送后会启动一个定时器,然后另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据

特点

  • TCP是面向连接的传输控制层协议
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
  • TCP提供可靠交付的服务
  • TCP提供全双工通信。数据在两个方向上独立的进行传输,因此,连接的每一端必须保持每个方向上的传输数据序号。
  • 面向字节流。面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但应用程序交下来的数据仅仅是一连串的无结构的字节流

TCP报文

在开始三次握手之前,看下TCP报文的数据结构

  • TCP首部
  • TCP数据部分
    在这里插入图片描述

着重看TCP头部结构,如下
在这里插入图片描述
了解一下什么是序列号和确认号

  • Sequence number

表示的是我方(发送方)这边,这个packet的数据部分的第一位应该在整个data stream中所在的位置。(注意这里使用的是“应该”。因为对于没有数据的传输,如ACK,虽然它有一个seq,但是这次传输在整个data stream中是不占位置的。所以下一个实际有数据的传输,会依旧从上一次发送ACK的数据包的seq开始)

  • Acknowledge number

表示的是期望的对方(接收方)的下一次sequence number是多少,一旦连接建立成功,ACK值一直为1。

三次握手

三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。

在这里插入图片描述
第一次握手:标志位SYN = 1,随机生成一个序列号seq1 = x
第二次握手:标志位SYN ,ACK = 1,确认号ack = x + 1,随机生成一个序列号seq2=y
第三次握手:标志位ACK = 1, 确认号ack = y + 1,seq2= x + 1

SYN/FIN的传输虽然没有data,但是会让下一次传输的packet seq增加一,但是,对于ACK的传输,不会让下一次的传输packet加一,也就是说,下一个实际有数据的传输,依旧从上一次发送ACK的数据包的seq开始计算

网络抓包分析

上面给了具体的连接过程,但是偏理论,下面实战一下,通过抓包进行分析
在这里插入图片描述
具体查看每一次握手都做了什么(主要看序列号,确认号)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有图有真相,不怕你不信
参考链接:https://www.jianshu.com/p/15754b4e9458

常见问题

问题一:为什么不是两次握手,而是三次握手

前两次握手客户端可以确认服务端的接收和发送是正常的(一个来回),但是服务端却不知道客户端的发送能力是否正常,那 TCP 的可靠性就无从谈起,所以需要第三次握手来确认双方的收发能力,以确保TCP连接的可靠性。

问题二:TCP的三次握手都可以携带数据吗?如果不是,那么哪一次握手可以携带数据,其他的为啥不能携带数据?

假设第一次握手客户端携带数据到服务器,服务器解析并存储此次连接的信息,如果数据量大,服务端就要分配足够的内存来进行存储,假如有黑客while(1000000000)来新建连接,结果可想而知,服务器将会被占用大量的内存。
第三次握手,此时对于客户端来说,连接已经建立,客户端携带数据完全没有问题

问题三:传输的过程中,报文丢失了怎么办

  • 第一次握手报文丢失
客户端发送 SYN 报文,然后进入到 SYN_SENT 状态。
客户端迟迟收不到服务端的 SYN-ACK 报文,就会触发客户端的超时重传机制。
在 Linux 里,客户端的 SYN 报文最大重传次数由/proc/sys/net/ipv4/tcp_syn_retries内核参数控制,这个参数是可以自定义的,默认值一般是 5。每次超时的时间是上一次的 2 倍。当第五次超时重传后,会继续等待 32 秒,如果服务端仍然没有回应 ACK,客户端就不再发送 SYN 包,然后断开 TCP 连接。
  • 第二次握手报文丢失
第二次握手时,服务端会进入 SYN_RCVD 状态
客户端角度:客户端第一次握手发出去的报文没有得到回复,那么客户端就会觉得自己的 SYN 报文丢失,于是客户端就会触发超时重传机制,重传 SYN 报文。
服务端角度:发送SYN_ACK报文后将会开启一个定时器,如果报文没有得到回应,就会触发超时重传机制,重传 SYN-ACK 报文,重传的次数由/proc/sys/net/ipv4/tcp_synack_retries控制,默认是5次。
  • 第三次握手报文丢失
服务端角度:发送SYN_ACK报文后将会开启一个定时器,如果超过了定时器设置的时间都没有收到客户端的ACK,将会重发SYN_ACK包。由/proc/sys/net/ipv4/tcp_synack_retries控制,默认是5次。
客户端角度:此时非彼时,现在我是 ACK 报文,拥有独特的权限,所以我是不会重传的

问题四:什么情况下报文失效或丢弃

  • 服务端的半连接队列(syns quene)满了,客户端就一直在超时重传 SYN 报文,直到达到最大的重传次数
  • 服务端的连接队列(accept quene)满了
    在这里插入图片描述

TCP的全连接和半连接队列

当服务端调用listen()函数监听端口的时候,内核会为每个监听的socket创建两个队列

  • 半连接队列(syn queue):客户端发送SYN包,服务端收到后回复SYN+ACK后,服务端进入SYN_RCVD状态,这个时候的socket会放到半连接队列。
  • 全连接队列(accept queue):当服务端收到客户端的ACK后,socket会从半连接队列移出到全连接队列。当调用accpet函数的时候,会从全连接队列的头部返回可用socket给用户进程。

在4.3版本之前的内核,SYN队列的最大大小以前是用net.ipv4.tcp_max_syn_backlog来配置,但是现在已经不再使用了。
现在用net.core.somaxconn来同时表示SYN队列和Accept队列的最大大小

查看某一个端口(也就是一个服务)的连接状况
ss 命令
ss是Socket Statistics的缩写。顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。

# ss
Netid  State  Recv-Q  Send-Q  Local Address:Port  Peer Address:Port
tcp    ESTAB  0       0       10.0.2.10:ssh       10.0.2.2:52316

Recv-Q:半连接队列
Send-Q:全连接队列


http://chatgpt.dhexx.cn/article/79ZfeRP1.shtml

相关文章

TCP为什么三次握手?

参考:公众号 小林coding 常见回答:三次握手保证双方都具有接受和发送数据的能力。 主要原因: 1. 防止重复历史连接的初始化 2.同步双方初始序列号 3.避免资源的浪费 1. TCP为什么三次握手? 1.1 防止重复历史连接的初始化 序…

【Java】TCP的三次握手和四次挥手

文章目录 一、三次握手三次握手的流程 二、四次挥手认识两个重要的状态 三、总结 一、三次握手 TCP三次握手是一个经典的面试题,它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接,并进行数据传递。(客户端主动发起的)…

什么是TCP的三次握手?

三次握手是指建立一个 TCP 连接时,需要客户端和服务端发送三个数据包的过程。进行三次握手是为了确定双方的接收能力和发送能力是否正常。 刚开始客户端处于 Closed 状态,服务端处于 Listen 状态。 第一次握手: 客户端给服务端发送一个 SY…

TCP 三次握手 四次挥手

三次握手 三次握手过程描述 第一次握手: 客户端发送syn标志位和seq num,向服务器申请建立连接,客户端状态由closed变为syn_send 第二次握手: 服务端返回 syn和ack标志位,ack num以及seq num,确认第一次握手的报文段,…

Go_详解TCP协议三次握手四次挥手

三次握手: 三次握手表示建立通信阶段,在TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠,由于这种面向连接的特性, TCP协议可以保证传输数据的安全&#xff0c…

一文读懂TCP的三次握手(详细图解)

在学习TCP三次握手的过程前,首先熟悉几个缩写简称: TCB 传输控制块,打开后服务器/客户端进入监听(LISTEN)状态 SYNTCP报文标志位,该位为1时表示发起一个新连接ACKTCP报文标志位,该位为1时&…

TCP的三次握手与四次挥手的全过程

三次握手 (1)第一次握手:建立连接时,客户端发送syn包(seqj)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号。 (2)服…

简述TCP的三次握手过程

TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(synj)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers) 第二次握…

TCP-三次握手

文章目录 三次握手简单示意图详细分析 一些思考为什么是三次握手?SYN 攻击什么是SYN 攻击?如何防止SYN 攻击?数据包丢失了该怎么办?初始序列号为什么随机产生?为什么 SYN 段不携带数据却要消耗一个序列号呢&#xff1f…

计算机网络之TCP三次握手

文章目录 计算机网络之TCP三次握手1.TCP三次握手过程2.TCP三次握手原因,而不是两次3.TCP三次握手原因,而不是四次4.TCP三次握手能携带数据吗5.三次握手连接阶段,最后一次ACK包丢失,会发生什么6.TCP 握手为什么是三次,为…

网络通信TCP协议三次握手

TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于IP的传输层协议。TCP在IP报文的协议号是6。TCP是一个超级麻烦的协议,而它又是互联网的基础,也是每个程序员必备的基本功。首先来看看OSI的七层模…

栈溢出实例--笔记三(ret2libc)

栈溢出实例--笔记三(ret2libc) 1、栈溢出含义及栈结构2、ret2libc基本思路3、实战3.1、二进制程序如下3.2、查看栈结构3.3、第一次栈溢出3.4、第二次栈溢出 1、栈溢出含义及栈结构 请参考栈溢出实例–笔记一(ret2text) 栈溢出实例–笔记二&a…

ret2libc3

文章目录 ret2libc31.程序分析2.栈帧设计3.exp编写 ret2libc3 当前的ret2libc3:无system,无”\bin\sh“ 1.程序分析 首先file一下,发现是32位程序: checksec一下,发现没有开启pie ida分析程序: 发现有个Se…

PWN题型之Ret2Libc

文章目录 前言0x1 :使用前提条件0x2 :解题思路0x3 :32位程序libc题型模板0x4 :代码的解析0x5 :64位程序实例 前言 菜鸡总结,如有不对,请不吝赐教。 0x1 :使用前提条件 存在溢出条件…

【PWN · ret2libc】[2021 鹤城杯]babyof

Linux_64的经典ret2libc题目,有必要好好整理总结一下其中的流程和注意点 目录 前言 一、题目重述 二、exp(思考与理解在注释) 三、经验总结 攻击步骤: 注意要点 四、疑问 前言 64位Linux和32位Linux确乎有着关于参数传递上的不同&a…

运行不同版本libc

author: Tamako 先上两个美化的链接,不用zsh的 字体 样式,颜色 成品 切换libc 我的工具机是Ubuntu 18.04。 获取libc版本 这个很容易,通过运行libc就可以直接获取,比如buu的Ubuntu16.04 32位机使用的libc 当然有些libc运行…

ret2libc实战

title: ret2libc实战 date: 2021-05-13 22:00:00 tags: binary securitystudy reportret2libc comments: true categories:ctfpwn ret2libc是一个pwner必备的基础知识。 ret2libc为return to libc的缩写,我们需要执行libc函数里面的system("/bin/sh") …

WSL vhdx非root误删除libc.so.6

思路 由于不在root这种情况的特殊性,没有办法使用网上例如LDPRELOAD进行软连接。则使用linux挂载ext4格式的vhdx然后重新进行软链接 挂载vhdx wsl ubuntu 20.04的虚拟磁盘在windows下的这个目录,不同的发行版在package目录下的地址不一样 在Package目…

ret2libc

一、原理 payload padding1 address of system() padding2 address of “/bin/sh” Padding1 随意填充, 长度刚好覆盖基地址 长度与shellcode处的一样的方法 address of system() 是system在内存中的地址,用来覆盖返回地址 system()函数地址在哪里? 从动态库中获取,计…

libc

1. libc (1). libc是Standard C library的简称,它是符合ANSI C标准的一个函数库。 libc库提供C语言中所使用的宏,类型定义,字符串操作函数,数学计算函数以及输入输出函数等。 正如ANSI C是C语言的标准一样,lib…