计算机网络入门(四)——TCP协议的3次握手与4次挥手过程详解
来源
https://blog.csdn.net/weixin_45160969/article/details/99240740?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight
http://www.52im.net/thread-258-1-1.html
TCP报文格式
TCP
报文由首部(标头)和数据两部分组成。首部一般由20-60
字节构成,长度可变。其中前20
字节格式固定,后40
字节为可选。TCP
报文中数据部分是可选的,即TCP
报文可以不包含数据(同理IP
包也可以不包含数据)。不含数据的TCP
报文通常是一些确认和控制信息类的报文,如TCP建立连接时的三次握手和TCP终止时的四次挥手等。
- 源端口号:
16
位的源端口字段包含初始化通信的端口号。 - 目的端口号:
16
位的目的端口字段定义传输的目的。这个端口指明接收方计算机上的应用程序接口。 - 序列号(
Seq
):TCP
数据包的编号。序列号是一个32位的数。 - 确认号(
ack
):TCP
使用32位的确认号字段标识期望收到的下一个段的第一个字节,并声明此前的所有数据已经正确无误地收到,因此,确认号应该是上次已成功收到的数据字节序列号加1。收到确认号的源计算机会知道特定的段已经被收到。确认号的字段只在ACK标志被设置时才有效。 - 首部长度(数据偏移):长度为4位,用于表示TCP报文首部的长度。用4位(bit)表示,十进制值就是[0,15],一个TCP报文前20个字节是必有的,后40个字节根据情况可能有可能没有。如果TCP报文首部是20个字节,则该位应是20/4=5。
- 保留位:长度为6位,必须是0,它是为将来定义新用途保留的。
- 标志:长度为6位,在
TCP
报文中不管是握手还是挥手还是传数据等,这6位标志都很重要。6位从左到右依次为:
URG:紧急标志位,说明紧急指针有效;
ACK:确认标志位,只有当 ACK=1 时确认号字段才有效.当 ACK=0 时,确认号无效
PSH:推标志位,置位时表示接收方应立即请求将报文交给应用层;
RST:复位标志,用于重建一个已经混乱的连接,用来复位产生错误的连接,也会用来拒绝错误和非法的数据包。
SYN:同步标志,该标志仅在三次握手建立TCP连接时有效,发起一个新连接。
FIN:结束标志,表示发送端已经发送到数据末尾,数据传送完成,发送FIN标志位的TCP段,连接将被断开。
- 窗口大小:长度为16位,
TCP
流量控制由连接的每一端通过声明的窗口大小来提供。通信的时候,发送方一次性发送10个数据包,即"发送窗口"的大小为10
。 - 检验和:长度为
16
位,该字段覆盖整个TCP
报文端,是个强制性的字段,是由发送端计算和存储,到接收端后,由接收端进行验证。 - 紧急指针:长度为
16
位,指向数据中优先部分的最后一个字节,通知接收方紧急数据的长度,该字段在URG
标志置位时有效。 - 选项:长度为0-40B(字节),必须以4B为单位变化,必要时可以填充0。通常包含:最长报文大小(MaximumSegment Size,MSS)、窗口扩大选项、时间戳选项、选择性确认(Selective ACKnowlegement,SACK)等。
- 数据:可选报文段数据部分。
3次握手过程详解
所谓三次握手(Three-Way Handshake)即建立TCP
连接,就是指建立一个TCP
连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:
(1)第一次握手:Client
将标志位SYN
置为1,随机产生一个值数据包编号seq=J
,并将该数据包发送给Server
,Client
进入SYN_SENT
状态,等待Server
确认。
(2)第二次握手:Server
收到数据包后由标志位SYN=1
知道,Client
请求建立连接,Server
将标志位SYN和标志位ACK都置为1
,确认号ack=J+1
,随机产生一个值数据包编号seq=K
,并将该数据包发送给Client
以确认连接请求,Server
进入SYN_RCVD
状态。(因为建立三个连接的tcp
数据包是确认和控制信息类的报文,是不含数据的,所以ack=J+1
)
(3)第三次握手:Client
收到确认后,检查标志位ack
是否为J+1
,确认号ACK
是否为1,如果正确则将标志位ACK置为1,确认号ack=K+1
,并将该数据包发送给Server
,Server
检查确认号ack
是否为K+1
,标志位ACK是否为1
,如果正确则连接建立成功,Client
和Server
进入ESTABLISHED
状态,完成三次握手,随后Client
与Server
之间可以开始传输数据了。
SYN攻击
SYN
攻击就是Client
在短时间内伪造大量不存在的IP地址,并向Server
不断地发送SYN
包,Server
回复确认包,并等待Client
的确认,由于源地址是不存在的,因此,Server
需要不断重发直至超时,这些伪造的SYN
包将占用未连接队列,导致正常的SYN
请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN
攻击时一种典型的DDOS
攻击,检测SYN
攻击的方式非常简单,即当Server
上有大量半连接状态且源IP
地址是随机的,则可以断定遭到SYN
攻击了,使用如下命令可以让之现行:
#netstat -nap | grep SYN_RECV
解决方法:https://blog.csdn.net/maque0312/article/details/6759085?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight
4次挥手过程详解
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:
全双工(Full Duplex)是通讯传输的一个术语。通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合
由于TCP
连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到另一个方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。‘
第一次挥手:Client
发送一个FIN
和确认号ack=M
,用来关闭Client
到Server
的数据传送,Client
进入FIN_WAIT_1
状态。
第二次挥手:Server
收到FIN
后,发送一个标志位ACK
给Client
,确认序号ack
为收到序号+1
(与SYN相同,一个FIN占用一个序号),Server
进入CLOSE_WAIT
状态。
第三次挥手:Server
发送一个FIN
,用来关闭Server
到Client
的数据传送,Server
进入LAST_ACK
状态。
第四次挥手:Client
收到FIN
后,Client
进入TIME_WAIT
状态,接着发送一个ACK
给Server
,确认序号为收到序号+1
,Server
进入CLOSED
状态,完成四次挥手。
常见面试题
1.三次握手是什么或者流程?四次握手呢?
答案前面分析就是。
2.为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为服务端在LISTEN
状态下,收到建立连接请求的SYN
报文后(第一次握手),把ACK
和SYN
放在一个报文里发送给客户端(第二次握手)。而关闭连接时,当收到对方的FIN
报文时(第一次挥手),仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close
,也可以发送一些数据给对方后,再发送FIN
报文给对方来表示同意现在关闭连接,因此,己方ACK
和FIN
一般都会分开发送。
简单说:
就是三次握手的时候,第二次握手是标志位ACK和标志位SYN放一个数据包里头一次性发给了客户端;
四次挥手的时候,因为第一次挥手时,只是表示客户端不再发送数据给服务端了,但是不表示服务端不发数据给客户端了啊,客户端还是能接受数据,只是不能发数据了而已,所以你可能还需要发送一些数据给对方之后,再发送FIN
报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK
报文和FIN
报文多数情况下都是分开发送的。
Wireshark抓包分析TCP三次握手
https://www.cnblogs.com/mq0036/p/11187138.html
1.wireshark
抓包获取访问指定服务端数据包Step1
:启动wireshark
抓包,打开浏览器输入www.huawei.com
Step2
:输入过滤条件获取待分析数据包列表 http
右键点击选中 追踪流 > tcp流,如下:
会看到下图所示:
可以发现,wireshark
截获到了三次握手的三个数据包。第四个包才是HTTP
的, 这说明HTTP
的确是使用TCP
建立连接的。
第一次握手:
客户端向服务器发送连接请求包。
数据包的关键属性如下:
SYN :标志位syn=1,表示请求建立连接
Seq = 0 :初始建立连接值为0,数据包的相对序列号从0开始,表示当前还没有发送数据
ack =0:初始建立连接值为0,已经收到包的数量,表示当前没有接收到数据
第二次握手:
服务器收到客户端发过来报文,由syn=1知道客户端要求建立联机。
向客户端发送一个的TCP报文
数据包的关键属性如下:
[SYN + ACK]: 标志位,同意建立连接,并回送SYN+ACK,并且都是1
Seq = 0 :初始建立值为0,表示当前还没有发送数据
ack = 1:表示当前端成功接收的数据位数,虽然客户端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位。(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)
第三次握手的数据包:
客户端再次发送确认包, SYN
标志位为0,ACK
标志位为1.并且把服务器发来的序号字段seq+1,放在确定字段中发送给对方.。
客户端收到服务器发来的包后检查确认序号(ack)是否正确,即第一次发送的序号加1(0+1=1)。以及标志位ACK是否为1。若正确,服务器再次发送确认包,ACK标志位为1,SYN标志位为0。确认序号(ack=0+1=1),发送序号为0+1=1
客户端收到后确认序号值与ACK=1则连接建立成功,可以传送数据了。
通过Wireshark来理解TCP 4次挥手过程
https://www.cnblogs.com/bylijian/p/8565601.html
本文地址:https://blog.csdn.net/weixin_42412601/article/details/107187592