linux网络报文发送前加包头,linux网络编程系列(四)--tcp包头、三次握手、四次挥手、状态...

本文详细介绍了TCP数据包头的结构,包括源端口、目的端口、序号、确认号等关键字段。接着,阐述了TCP的三次握手过程,确保连接的可靠建立,以及四次挥手的断开连接机制,确保数据传输的完整性和避免资源浪费。此外,提到了TCP的状态转换,如ESTABLISHED、FIN_WAIT1、TIME_WAIT等,并解释了TIME_WAIT等待2MSL的原因,确保连接彻底关闭和数据可靠性。
摘要由CSDN通过智能技术生成

1. TCP协议

1.1 TCP数据包头

要了解三次握手和四次挥手,首先需要了解下TCP数据包头的结构,如下:

64ddf59530ed2af0f9ea0f54b89ada9e.png

源端口、目的端口:16位长,标识出远端和本地的端口号;

序号:SEQ,32位长,标识发送的数据包的顺序,防止数据包乱序;

确认号:32位长,接收方对发送方发送来的TCP报文段的响应,其值是对收到的报文序号加1,用于解决不丢包的问题;

TCP头长:4位头长,标识tcp头部可以有多少个32bit,即多少个4字节,因为头长是4位,最大能表示15,所以TCP头部最大就是15*4等于60个字节,也就是说TCP包头最长可以有60个字节;

URG:表示紧急指针是否有效;

ACK:ACK位置1表明确认号是合法的,如果ACK为0,那么数据包不包含确认信息,确认字段被省略;

PSH:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间;

RST:表示要求对方重新建立连接,用于复位由于主机崩溃或其他原因而出现的错误的连接,还可以用于拒绝非法的数据报或拒绝连接请求;

SYN:表示请求建立连接;

FIN:表示通知对方要关闭连接了;

窗口大小:16位长,是一种流量控制的手段,这个窗口,指的是接收通告窗口,它告诉对端本端的TCP缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度;

校验和:16位长,由发送端填充,接收端根据该值,校验接收到的TCP报文段在传输过程中是否损坏,校验包括头部和数据部分,它是TCP可靠传输的一个重要保障;

紧急指针:16位长,是一个正的偏移量,它和序号相加表示最后一个紧急数据的下一个字节的序号,确切的说,它是紧急指针相对当前序号的偏移,是发送端向接收端发送紧急数据的办法;

可选项:TCP头部最长可以有60个字节,而前部分已知的字段占用了20个字节,所以选项最多可以有40个字节,包括最大TCP载荷,窗口比例、选择重复数据报等选项;

注意:TCP数据包是没有IP地址的,只有端口

1.2 三次握手协议

在利用TCP实现源主机和目的主机通信时,目的主机必须同意,否则TCP连接无法建立。为了确保TCP连接的成功建立,TCP采用了一种称为三次握手的方式,三次握手方式使得“序号/确认号”系统能够正常工作,从而使它们的序号达成同步。如果三次握手成功,则连接建立成功,可以开始传送数据信息。 三次握手:为应用程序提供可靠的通信连接,适合于一次传输大批数据的情况,并适用于要求得到响应的应用程序。 其三次握手分别为:

源主机A的TCP向主机B发送连接请求报文段,其首部中的SYN(同步)标志位应置为1,表示想跟目标主机B建立连接,进行通信,并发送一个同步序列号X(例:SEQ=100)进行同步,表明在后面传送数据时的第一个数据字节的序号为X+1(即101), 此时client端状态为SYN_SENT。

目标主机B的TCP收到连接请求报文段后,如同意,则发回确认。再确认报中应将ACK位置为1.确认号为X+1,同时又向A也发送一个SYN=1,并发送一个序号Y, 此时server端状态为SYN_RCVD。

源主机A的TCP收到目标主机B的确认后要想目标主机B给出确认。其ACK置为1,确认号为Y+1,而自己的序号为X+1。TCP的标准规定,SYN置1的报文段要消耗掉一个序号, 当两边都确认完成后,状态改为ESTABLISHED。

运行客户进程的源主机A的TCP通知上层应用进程,连接已经建立。 当源主机A向目标主机B发送第一个数据报文段时,其序号仍为X+1,因为前一个确认报文段并不消耗序号。 当运行服务进程的目标主机B的TCP收到源主机A的确认后,也通知其上层应用进程,连接已经建立。至此建立了一个全双工的连接。

1.3 tcp断开连接四次挥手

tcp建立连接是三次,但断开连接却要四次,是因为tcp是全双工的,两个方向上都需要进行关闭。

当主机A完成数据传输后,将控制位FIN置1,向主机B提出停止TCP连接的请求,状态改为FINWAIT1,此时,该数据包中,序列号为主机B发送的上一个数据包中的确认号值,而确认号为主机A发送的上一个数据包中的序列号+该数据包所带的数据的大小;

主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1,此时服务器状态改为CLOSEWAIT, 客户端状态改为FINWAIT_1,此时序列号为上一步中的确认号,确认号为上一步中的序列号加1;

由B 端再提出反方向的关闭请求,将FIN置1,服务端状态为LASTACK,客户端状态为TIMEWAIT,此时序列号为上一步的确认号,确认号为上一步的序列号加上数据包所带数据的大小;

主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束状态为CLOSED,此时序列号为上一步中的确认号,确认号为上一步中的序列号加1;

注意 : FIN和SYN一样,也要消耗一个序号。理论上服务器在TCP连接关闭时发送的终止数据包中,只有终止位置是1,然后客户端进行确认。但是在实际的 TCP实现中,在终止数据包中,确认位和终止位是同时置为1的,确认位置为1表示对最后一次传输的数据进行确认,终止位置为1表示关闭该方向的TCP连 接。

1.4 TCP有哪些状态

一般我们可以使用netstat查看当前socket状态。

CLOSED:表示初始状态;

LISTEN:表示服务器端的某个socket处于监听状态,可以接受连接;

SYNSENT:三次握手时,客户端发送第一次SYN连接请求后,状态SYNSENT;

SYN_RCVD:也是三次握手时服务端的一个中间状态;

ESTABLISHED:表示连接已经建立,这里要说明一下,其实TCP连接并不是真的有什么东西连着在,只是说双方都是ESTABLLISHED状态,就说明双方连接正常;

FINWAIT1:已经建立连接后,其中一方请求终止连接,四次挥手中间状态;

TIME_WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL(默认是2min)后回到CLOSED可用状态;

CLOSING:表示发送FIN报文后,没有收到对方的ACK报文,反而收到了对方的FIN报文,这种情况其实就是双方同时关闭socket;

CLOSE_WAIT:四次挥手中间状态,表示在等待关闭连接;

LAST_ACK:四次挥手时被动关闭一方在发送FIN报文后,等待对方的ACK确认报文;

RST:同时打开和同时关闭;

1.5 TIME_WAIT为什么要等2MSL才会变为CLOSED

有两个原因:

可靠地终止TCP连接,在四次挥手的最后一步中,可能客户端发送到服务端的确认包丢失,服务端就会重发结束报文段,客户端重新发起确认报文段,而这就需要停留一段时间;

保证让迟来的TCP报文段有足够的时间被识别并丢弃,如果没有停留一段时间,原来客户端的端口号就可以立即被另外一个应用程序重用,此时如果服务端有迟来的报文段,就会发到该新的应用程序上去,而这显然是不被允许的;

注意:报文段的生存周期是一个MSL,所以在2MSL后,不会还存在迟到的报文段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值