linux网络中TCP包的组成及其中各部分含义详解

**

因为本人之前一直写的是云笔记,对自己学会的东西作一个总结,所以基本都是文字,本来想全发成博客的形式,发现全发成博客比较花费时间,而且一直发博客质量不是很好,而且通过发博客学到的东西也会变少,所以准备先把笔记发出来,后续再将它们改成博客的形式,争取2天至少改一篇博客,觉得我总结的还行的可以先关注我,后续会发成博客形式,内容也会更加完善

**

TCP包:
TCP包的首部信息由以下几部分组成,1、源端口号(16位),表示自己主机要发送数据包的进程是哪个;2、目标端口号(16位),表示发送要将自己的数据包,发送给目标主机的哪个进程;3、***(32位),是用来标识发送数据的顺序的,每发送一个数据包,下一个***就会变成,此***加上数据包中数据的大小, 并且这个***并不会从0开始,而是随机生成一个***,然后按照发送数据包的大小进行累加,具体它的含义,可以看我之前总结的TCP***机制;4、确认应答***(32位),它表示接收端收到了发送端发送的数据包,并且对这个数据包的***进行确认回复,回复的方式是发送端数据包的***,加上发送端数据包中数据的大小,具体它的含义,可以看看我之前总结的确认应答机制;5、数据偏移(4位),这个部分虽然只有四位,但是它的单位是4字节,也就相当于这个部分的值算出来后,要乘以4,然后单位变成字节,比如0010,换成10进制的话就表示,2*4=8字节,它的功能是用来表示真正数据部分和TCP首部的偏移量,也就是数据部分从哪个字节开始,也可以表示这个TCP包的首部有多大;6、保留(4位),这部是为了以后扩展用的(为了扩展标志位 ),目前没有什么用,一般情况下置0,即使不置0也不会影响这个TCP包;7、控制位(8位),它是用来表示标志位的,一共有8个标志,只要这8位中哪个位为1,就是表示哪个标志有效,从左往右第一个标志位是CWR,当它标志为1时,表示已经将拥塞窗口缩小(如果不知道拥塞窗口,可以看我之前总结的TCP的拥塞窗口机制,同时这个字段也影响IP首部,相当于区分服务中的ECT标志位),第二个标志位是ECE,如果这个标志位为1,表示从发送端到接收端的网络环境拥塞(同时这个字段也影响IP首部,相当一起区分服务中的CE段),第三个标志位为URG,如果这个标志位为1,表示这个数据包中有紧急要处理的数据 ,第四个标志位为ACK,这个标志位为1时,表示确认应答有效(如果不知道ACK,可以看看我之前总结的确认应答机制),第五个标志位为PSH,这个标志位为1时,表示让接收端将此数据包立即上传给上层应用协议,如果为0则表示不用立即上传,而是先进行缓存,第六个标志位为RST,这个标志位为1时,表示TCP连接出现异常,需要强制断开连接,第七个标志位为SYN,这个标志位为1时,表示在进行三次握手建立连接时,客户端需要向服务端先发送一个SYN请求,表示想和服务端建立连接(如果不知道三次握手机制,可以看我之前总结的三次握手),第八个标志位为FIN,这个标志位为1时,表示希望断开TCP连接(正常断开),在进行四次挥手时,用FIN来表示要开始断开连接了(如果不了解四次挥手的过程,可以看我之前总结的四次挥手);8、窗口大小(16位),用来表示接收端允许的窗口大小是多少(如果不清楚窗口含义的,可以看看我之前总结的滑动窗口机制和流量控制机制),如果这个窗口大小是0,表示发送的是一个窗口探测
9、校验和(16位),它是用来检验TCP数据包是否在传输途中受到损坏,保证数据的正确性的,它校验的方法就是利用这16位由0和1组成的校验码,进行检验,不过在用校验和进行检验时,检验的不是TCP首部,而是TCP伪首部(它在TCP首部信息的前面一共12字节),伪首部包含以下几个信息,第一个是源IP地址(32位),表示发送TCP包的主机IP地址,第二个是目标IP地址(32位),表示接收此数据包主机的IP地址,第三个是填充(8位),在进行校验时长度必须是16的整数倍,如果不够就用这个位置补0,凑够16位,第四个是协议号(8位),表示传输数据包时所用的协议是哪个,第五个是TCP包长度(16),表示整个TCP包多大(包含首部大小),进行检验的算法是,先将校验码置0,然后将这五个部分的二进制值取反(如果那四个部分的位数不是16位的整数倍,则由填充位来补,补在最前头,因为这样不影响这四个部分位数的大小,为什么要是16的整数倍,原因是,在计算时是以16位为单位,进行相加的,所以如果有一方不是16位那就没办法相加了),然后再逐个相加,如果相加的值大于16位,那么就将前16位拿出来,再后后16位相加,如果还是大于16位,就继续这样相加,直到是16位了(这里可能会有疑问,在加完一次之后,可能就不是16的整数倍了,但实际上不是这样了,在加完之后,前面的0并没有被丢弃,所以可以继续就16位的形式进行相加),最后再对之前我们置0的校验码取反,然后进行再加上它,最终得到最后的值,把这个值,加在之前为0的校验码上,就是真正的校验码了,在接收端进行校验时,按照之前的方法先将伪首部的二进制取反进行相加,然后再加上此TCP包的校验码,如果最终的结果为全1,那么就表示这个TCP包是正确的(最终会得到全1的原因是,我们之前在进行取反相加后,在最后加了16位全为1的值(它是对0进行了取反,为什么要将最初的校验值设为0,原因是如果设为其它数,在最后得到真正校验值的时候,会出现很大的问题,因为你的初值不是0,所以在进行最后相加时,如果加数据很大,那么还可能造成数据溢出问题,这不好处理,而如果初值不是0,那么在进行校验时不好校验,因为在校验时,既要校验0也要校验1),所以在相加后,必然会溢出,在溢出后又会从0开始计算,所以计算出的值就相当于是还差多少位,就是16位全为1的值了,所以我们在校验时加上正确的校验码,会得到全为1的值,如果不是,那么就代表这个TCP包损坏了),最后就是为什么要进行这种取反相加的操作,而不直接进行相加得到,也是为了在安全上考虑;因为TCP包首部只有,源端口号和目标端口号,而在进行通信时是由源端口号和目标端口号,源IP地址 和目的IP地址,协议号五部分来确定一个通信的,所以如果其它三部分损坏了,但TCP包是不能察觉的,所以就有了伪首部(伪首部是在TCP包首部前面放着),来进行校验,判断此TCP包是否被损坏
10、紧急指针(16位),这个部分只有在标志位URG为1有效时,才会使用,它是用来表示紧急数据在哪个位置,一般情况下,紧急数据是指,从数据开头到紧急指针所指的位置为紧急数据,需要立即进行处理;11、选项(24位),选项部分是一个可选部分,它其中有很多选项,可以根据我们的需要来进行选择,不同的选项用不同的位数来表示;12、填充(8位),是用来补0的,因为选项只有24位,但这个部分必须是32的整数倍,因为TCP包要求这两个位置必须等于32位;13、数据部分(32位),这个部分虽然有32位,但它的长度是不确定的,因为在加上TCP包的首部后,不能超过TCP包限制的总大小

linux网络中TCP包的组成及其中各部分含义详解