TCP:面向连接的运输
TCP协议是面向连接的协议,把连接作为最基本的抽象。每一条TCP连接唯一的被通信两端的两个端点所确定。TCP协议是点对点,而不是点对多点。端点又被称为套接字,TCP协议规定,IP地址拼接端口号就构成套接字。
预备知识:
1 可靠数据运输原理:
1、TCP协议发送两种数据包,一种数据包用来传输数据,一种数据包用来发送控制信息。TCP数据都会有一个包头,包头中有相应标志位,标志位的设定用于表明数据包是用于数据发送还是用于传输控制信息。
2 TCP建立一个连接需要三个报文段:
情况1:防止已失效的请求报文段突然又传送到了服务端而产生连接的误判。
客户端发送了一个连接请求报文段A到服务端,但是在某些网络节点上长时间滞留了,而后客户端又超时重发了一个连接请求报文段B该服务端,而后 正常建立连接,数据传输完毕,并释放了连接。但是请求报文段A延迟了一段时间后,又到了服务端,这本是一个早已失效的报文段,但是服务端收到后会误以为客户端又发出了一次连接请求,于是向客户端发出确认报文段,并同意建立连接。那么问题来了,假如这里没有三次握手,这时服务端只要发送了确认,新的连接就建立了,但由于客户端没有发出建立连接的请求,因此不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的连接已经建立了,并在 一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端判定为出了问题,才会关闭这个连接。这样就浪费了很多服务 器的资源。而如果采用三次握手,客户端就不会向服务端发出确认,服务端由于收不到确认,就知道客户端没有要求建立连接,从而不建立该连接。
情况2:防止形成死锁。
服务器的SYN和ACK报文段没有发送到客户端,服务器认为连接已经建立,但是客户端不知道服务器是否已准备好,不知道服务器建立什么样的序列号。客户端认为连接还未建立成功,将忽略服务器发来的任何数据分组,只等待连接确认应答分组。而服务器在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
3 TCP释放一个连接却需要四个报文段
第一个报文段,客户端向服务器发送释放连接报文段,释放连接报文段FIN置1,此时客户端序列号为w
第二个报文段,服务器回复确认收到客户端释放连接报文段的报文段,确认号u+1,之后客户端不会像服务器发送报文段,但是服务器可以向客户端发送报文段,全部发送完成服务器的序列号为v,客户端的确认号为v,但是客户端序列号为w+1
第三个报文段,服务器向客户端发送释放连接报文段,服务器序列号v+1,确认号还是w+1
第四个报文段,客户端回复确认收到服务器的释放连接报文段的报文段,,客户端的确认号+1,序列号+1。
服务器收到第四个报文段,就进入CLOSED状态;客户端要等待最长报文段寿命(2MSL),才进入到CLOSED状态。
注:
1、MSL是任何IP数据报能够在网络中存活的最长时间,每个数据报含有一个称为跳限(hop limit)的8位字段,它的最大值是255,即最大为255跳。具有最大跳限的数据报在网络中存在的时间不可能超过MSL秒。
2、客户端在TIME-WAIT状态必须2MSL的时间的两个理由:
可靠地实现TCP全双工连接的终止:第四个报文段如果丢失,在2MSL时间内服务器会重新发送第三报文段客户端接收到之后重新发送第四报文段。
防止“已失效的连接请求报文段”出现在本连接中,在2MSL时间之后,本连接持续的时间内所产生的所有报文段都会网络中消失。因为一个TCP端口不能同时被打开多次,如果没有TIME-WAIT状态,TCP端口关闭之后在TIME-WAIT时间内重新打开,可能会接受原来还没有消失的报文段,这是不能发生的!!!
4 TCP首段内容:
1、seq:序号。TCP协议是面向字节流的,在一个TCP连接中的传送的字节流的每一个字节都是按照顺序编号,seq需要占用4个字节,所以范围是[0 4294967296],序号可以重复使用。TCP规定,首部中序号字段值是本报文段所发送数据的第一个字节的序号。序号用于跟踪该端发送的数据量。4294967296个字节(2的32次方),如果不重复利用就是4G的数据量。序号为当前端成功发送的数据字节数,确认号为当前端成功接收的数据字节数,SYN标志位和FIN标志位也各自要占用1个序号。TCP的标准规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号。A(客户端)把自己的初始化序列号放在SYN数据包中发送给B(服务器),B收到后会回发一个SYN+ACK数据包,该数据包中B会把收到的来自A的序列号加一后的值发送回去(确认号),同时数据包中也包含B的初始化序列号,当A收到数据后发送一个ACK数据包其中包含了B发过来的序列号加一后所得的数值(确认号)。
2、ACK: 仅当ACK=1时确认字段才有效,当ACK=0时确认字段无效,并且TCP规定,在连接建立后所有的传送报文段都必须要把ACK置为1。
3、SYN:同步序列号,用来发起一个连接。当SYN=1而ACK=0时表明这是一个请求报文段;若对方同意连接,则响应报文中SYN=1,ACK=1。
4、FIN :用来释放一个连接,当FIN=1表示此报文段的发送方已经发送完毕。并要求释放链接。
5、SYN、ACK、FIN是标志位,在属性flag中,flag占用一个字节。含有SYN或FIN标志位的包并不携带有效数据。
注:SYN位被启动时,向对方告知自己(客户端或者服务器)的初始序列号以便对方知道如何接收自己发送过来的数据包。如果是ACK比特位被启动,它表明数据包用于通知接收方我收到了你上次发来的数据。
5 SYN FLOOD攻击
1、传输控制块TCB
用于封装传输数据的数据结构。一个TCB数据块包含了数据发送双方对应的socket信息以及拥有装载数据的缓冲区。
6 为什么序列号要是随机数:
初始序列号往往是一个任意值而不是每次都以1开始,试想一次数据发送中,一方想对方发送了一个序列号为1的数据包,由于网络原因该数据包没有抵达对方,并且因为网络没有恢复,双方只好中断当前连接建立新连接。如果新连接同样用1作为初始序列号,当连接建立后,如果上次因网络原因没有抵达的数据包突然抵达了,那么对方就以为上次发送的数据包是这次新连接后发送过来的数据包,为了防止这种异常情况,我们需要将初始序列号设置为随机数。
注:序列号应该不是随机的,而是由双方协商的,协商之前最开始的值由TCP运输层生成。 它可能是上一个该端口的序列号+1 ,
原因是为了避免上次已断开的连接,还存在网络中延迟到达的TCP报文段的序号与当前连接中等待报文段的序号相同,
以至于认为是这一次连接的包,发生错误。