详解TCP的三次握手
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:全连接队列
详解TCP的三次握手相关推荐
- 如何获取握手包_白话详解TCP的三次握手到底做了些什么
作 者:雨林 来 源:cnblogs.com/yuilin 广而告之:由于此订阅号换了个皮肤,系统自动取消了读者的公众号置顶.导致用户接受文章不及时.您可以打开订阅号,选择置顶(标星)公众号,重磅干货 ...
- 详解TCP协议三次握手四次挥手
三次握手: 三次握手表示建立通信阶段,在TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠,由于这种面向连接的特性, TCP协议可以保证传输数据的安全,所以应用十分广泛 ...
- 白话详解TCP的三次握手到底做了些什么!!!
作者:雨林 https://www.cnblogs.com/yuilin 首先简单介绍一下TCP三次握手 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建 ...
- TCP端口状态 LISTENING、ESTABLISHED、TIME_WAIT及CLOSE_WAIT详解,以及三次握手,滑动窗口
参考文章:端口状态 LISTENING.ESTABLISHED.TIME_WAIT及CLOSE_WAIT详解,以及三次握手,滑动窗口
- 端口状态 LISTENING、ESTABLISHED、TIME_WAIT及CLOSE_WAIT详解,以及三次握手,滑动窗口
本文根据众多互联网博客内容整理后形成,引用内容的版权归原始作者所有,仅限于学习研究使用 网上查了一下端口状态的资料,我下面总结了一下,自己学习学习: TCP状态转移要点 TCP协议规定,对于已 ...
- Linux网络编程---详解TCP
Linux网络编程---详解TCP的三次握手和四次挥手_shanghx_123的博客-CSDN博客_tcp的协议数据单元被称为 TCP协议详解(TCP报文.三次握手.四次挥手.TIME_WAIT状态. ...
- 三次握手和四次挥手图解_详解 TCP 连接的“三次握手”与“四次挥手”
作者 | AhuntSun 责编 | Elle TCP connection 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西: 由于TCP不存在连接的概念 ...
- 详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ”
作者 | AhuntSun 责编 | Elle TCP connection 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西: 由于TCP不存在连接的概 ...
- 详解 TCP 连接的“三次握手”与“四次挥手”
详解 TCP 连接的"三次握手"与"四次挥手" 前言 TCP的三次握手(Three-Way Handshake) 1."三次握手"的详解 2 ...
最新文章
- C# 淘宝商品微信返利助手开发-(六)返利助手开发(4)如何通过淘口令解析的出来的地址获得返利信息
- qtextedit 默认文案_QT-纯代码控件-QSplitter(分裂器)
- uni app map 地图 漂浮问题及方案
- 结构类型需要重载GetHashCode和Equals
- python中文界面设定_python绘图界面中文显示
- 华为联手沃达丰进行5G测试 传输速度达到20Gbit/s
- Swift与OC混编过程中的配置
- win10添加/关闭开机启动应用
- 蓝桥杯2019年第十届C/C++省赛A组第四题-迷宫
- kickstart部分重要参数
- JavaScript:Boolean对象
- 使用elasticsearch建立搜索引擎
- android 实现果冻动画效果,Android实现果冻滑动效果的控件
- 四川省天府新区知识产权信息公共服务网点申报好处条件材料
- python爬虫——实战篇
- python应用如何实现升级_基于esky实现python应用的自动升级详解
- 欧拉-伯努利梁横向振动2
- SAP如何将物料账期跨年月一次性开到当前
- 【Ogre编程入门与进阶】第十七章 Ogre3D 和CEGUI 的结合
- 手机html编辑器gb2312,所见即所得HTML编辑器 - KindEditor 2.4
热门文章
- RequestsDependencyWarning: urllib3 (1.26.9) or chardet (3.0.4) doesn‘t match a supported version
- 微信朋友圈是访问腾讯服务器吗,微信朋友圈疑似增加“来访”新功能?网友:再也不看朋友圈了!...
- 微信官宣:5000W个微信红包封面,可以秀一波了!!
- kafka启动过程中遇到问题:系统找不到指定路径
- 【无标题】前端工程师面试题手册-有点长但是很有用
- mysql删除注册表mysqld要删除吗_彻底删除Mysql方法
- linux ptrace,Linux ptrace 简介
- 网盘挂载Alist+RaiDrive 开机自启动导入播放列表
- 知乎热榜:如何看待 2021 年秋招算法岗灰飞烟灭?
- java异步调用方法