画图TCP协议和三次握手及四次挥手
Posted 天梯的脚印
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了画图TCP协议和三次握手及四次挥手相关的知识,希望对你有一定的参考价值。
1. TCP协议
1.1. TCP特性
1. TCP提供一种面向连接的、可靠的字节流服务在一个TCP连接中,仅有两方进行彼此通信。广播和多播不能用于TCP
2. TCP使用校验和,确认和重传机制来保证可靠传输
3. TCP给数据分节(给每一个传送的数据字节都编号)进行排序,并使用累积确认保证数据的顺序不变和非重复
4. TCP使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制
1.2. TCP包头结构
1. **源端口、目标端口**:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口
某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通
信。源端口、目标端口是用16位表示的,可推算计算机的端口个数为2^16个,即65536
2. **序列号**:表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字
节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从 0
开始
3. **确认号**:表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送方:
我希望你(指发送方)下次发送的数据的第一个字节数据的编号为此确认号
4. **数据偏移**:表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要
指定这个TCP报文段到底有多长。它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多
远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是
TCP首部最大60字节
5. **URG**:表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只
有当URG=1时才有效
6. **ACK**:表示是否前面确认号字段是否有效。只有当ACK=1时,前面的确认号字段才有效。TCP规
定,连接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段
7. **PSH**:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如
果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到
的数据读走,就会一直停留在TCP接收缓冲区中
8. **RST**:如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放
连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志
的TCP报文段称为复位报文段
9. **SYN**:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报
文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意
建立连接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报文段称为同步报文段
10. **FIN**:表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:“我的
数据已经发送完毕,你可以释放连接了”,带FIN标志的TCP报文段称为结束报文段
11. **窗口大小**:表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方
发送的数据量,达到此值,需要ACK确认后才能再继续传送后面数据,由Window size value *
Window size scaling factor(此值在三次握手阶段TCP选项Window scale协商得到)得出此值
12. **校验和**:提供额外的可靠性
13. **紧急指针**:标记紧急数据在数据字段中的位置
14. **选项部分**:其最大长度可根据TCP首部长度进行推算。TCP首部长度用4位表示,选项部分最长为:
(2^4-1)*4-20=40字节
2. TCP三次握手
2.1. 说明
1. TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。
2. 客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。
3. TCP建立连接时要传输三个数据包,俗称三次握手(Three-way Handshaking)
2.2. 三次握手过程详解
- 第一次握手(SYN=1, seq=x):
客户端发送一个 TCP的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口(请求同步),并选择序号 seq=x,表明传送数据时的第一个数据字节的序号是 x。(seq是个随机值).
发送完毕后,客户端进入 SYN_SEND 状态。
- 第二次握手(SYN=1, ACK=1, seq=y, ack=x+1):
服务器的TCP收到连接请求报文段后,如同意,则发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号(随机值y),放到seq 域里,同时将确认序号ack设置为客户的 ISN 加1,即 x+1(即回复对方确认收到了序列号为x开始的包,且希望下次的数据从x+1的位置开始)。
发送完毕后,服务器端进入 SYN_RCVD 状态。
- 第三次握手(ACK=1,ack=y+1,seq=x+1)
客户端收到此报文段后再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段ack中发送给对方,并且告诉服务器自己的seq=x+1.
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP握手结束。
3. TCP四次挥手
3.1. 说明
1.所谓四次挥手(Four-Way Wavehand)即终止 TCP 连接,就是指数据传送完毕需要断开一个 TCP 连接时,需要客户端和服务端总共发送 4 个包以确认连接的断开。在 socket 编程中,这一过程由客户端或服务端任一方执行`close`来触发。
2.由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个 TCP 连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
- 第一次挥手(FIN=1,seq=u)
1.假设客户端想要关闭连接,客户端发送一个FIN标志位置为 1 的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。因为有可能服务器还要发送数据,所以发送自己的序列号seq=u,等待服务器确认。
2.发送完毕后,客户端进入FIN_WAIT_1状态。
- 第二次挥手(ACK=1,seq=v,ack=u+1)
1.服务器端确认客户端的FIN包,发送一个确认包(ACK=1(确认),seq=v(自己的序列号),ack=u+1(确认收到序列号u以前的包,并希望下次发送数据从 u+1 开始)),表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接(可能有数据发送)。
2.发送完毕后,服务器端进入CLOSE_WAIT状态,客户端接收到这个确认包之后,进入FIN_WAIT_2状态,等待服务器端关闭连接。
3.在这过程中 TCP 服务器进程会通知高层应用进程。然后从客户端到服务器这个方向的连接就释放了,TCP 连接处于半关闭状态。但是服务器 若发送数据,客户端仍要接收。
- 第三次挥手(FIN=1,ACK=1,seq=w,ack=u+1)
1.若服务器已经没有要向客户端发送的数据,其应用进程就通知 TCP 释放连接。
2.服务器端准备好关闭连接时,向客户端发送结束连接请求FIN置为 1,ACK=1,seq=w(有数据发送过),ack=u+1。
3.发送完毕后,服务器端进入LAST_ACK状态,等待来自客户端的最后一个ACK。
- 第四次挥手(ACK=1,seq=u+1,ack=w+1)
1.客户端接收到来自服务器端的关闭请求,发送一个确认包(在确认报文段中ACK=1,确认号ack=w+1,自己的序号seq=u+1),并进入TIME_WAIT状态,等待可能出现的要求重传的ACK包。(这个确认包是内核进行发送的,上面不能发数据的是客户端的send函数)
2.服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。
3.客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的ACK,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。
以上是关于画图TCP协议和三次握手及四次挥手的主要内容,如果未能解决你的问题,请参考以下文章