概述: TCP 是Tranfer Control Protocol的简称,TCP是一种面向连接的、可靠的、基于传输层的通信协议。


一、TCP学习前奏:

因特网五层协议栈共有五层:应用层、传输层、网络层、链路层和物理层: 


因特网五层协议栈


然后看看OSI的七层模型: 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

OSI七层模型

在OSI七层模型中,每一层的作用和对应的协议如下: 


OSI七层模型每一层的作用和对应的协议


要进行更深层次的剖析,就需要了解并熟记TCP协议的数据格式和每个字段的含义:


TCP数据格式

数据格式解释:

Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接;

Sequence Number:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题;

Acknowledgment Number:32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题;

Offset:给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;

TCP Flags:TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为URG,ACK,PSH,RST,SYN,FIN。每个标志位的意思如下:

 URG:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据; 

ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;

PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;

RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;SY**N:表示同步序号,用来建立连接**。

SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手;

FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。Window:窗口大小,也就是有名的滑动窗口,用来进行流量控制;这是一个复杂的问题,这篇博文中并不会进行总结的;



二、理解TCP

tcp三次握手:

第一次握手:client端将标志符SYN=1, 随机产生 seq  Number = x,然后调用connection方法,将数据包发送为服务端,自己进入syn_sending状态;

第二次握手: server接收到client的请求后,有client的SYN=1,知道客户端要进行连接,这是将标志符SYN、ACK都设置为1,设置ack number = x+1;随机产生 seq  Number = y;将数据包发送给client,自己进入SYN_RECD状态;

第三次握手: client端收到server的返回和 i信息,首先验证server端的ack number 如果等于 seq number +1即x+1, 说明server已经同意它连接,然后设置自己的 ack number  = y+1 ,发送给sever,验证server 发送的seq+1是否等于client 的 ack number;如果等于说明连接成功,Client和Server进入ESTABLISHED状态;



tcp四次分手:



第一次分手:client设置控制符FIN=1,随机产生序列数seq=x,将数据包发送给server;client计入Finish_waite_1;

第二次分手: server收到,验证client的FIN=1,即断开连接,然后设置自己控制位ACK=1,随机生成序列数seq=m,ack确认数为x+1,发送给client ,client验证自己的序列数加一是server的ack确认数,client进入Finish_waite_2,告诉client,等待自己断开连接;

第三次连接:server设置控制符FIN=1,随机产生序列数seq=n;将数据包发送给client主动请求断开连接,自己进入last_wait状态;

第四次分手: client 验证 server是FIN包,确定是断开连接,生成ack number = server发送的seq +1 ;发送给server,自己进入time_wait,server收到后,验证客户端发送的ack number 是否是自己发送的seq+1,是的话,自己断开连接,客户端等待一端时间如果没有server的消息自己也断开连接


TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。


TCP的缺点: 慢,效率低,占用系统资源高,易被攻击    TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。


TCP 为什么是可靠的传输协议:

1. 建立连接期间 :syn 报文、ack 版本都有指定的 sqn 随机数检验

2. 数据传输期间 2.1 报文重传 2.2 滑动窗口 根据当前的网络情况设置包文的长度 每一个包文都会包含sqn 其实包文序号和length 长度 ,接收端收到以后都会返回指定的接收长度给发送端,发送端根据接收端确定的接受情况判断是否有丢包报文,如果有的话会将制定的包文进行重传 ;