关于TCP

TCP——传输控制协议

先来看看它的报文格式:

关于TCP

我先来简单介绍一下TCP这个协议,关于TCP最主要的特点主要有以下几点:

1. TCP是面向连接的运输层协议;

2. 每一条TCP连接只能 有两个断点,每一条TCP连接只能是点对点的;

3. TCP提供可靠交付的任务,即TCP传送的数据无差错,不丢失,不重复,并且按序到达;

4. TCP提供全双工的通信;

5. TCP是面向字节流的,TCP中的“流”指的是流入到进程或从进程流出的字节序列,TCP把应用程序交下来的数据      看成仅仅是一连串的无结构的字节流。

一、TCP报文中的URG与PSH字段各是什么意思?二者之间有什么区别?

1. 紧急URG:当URG=1时,表明紧急指针字段有效,它告诉系统此报文中有紧急数据,应尽快传送(相当于高优先      级的数据),而不要按照原来的排队顺序来传送。

   当URG置1时,发送应用进程就告诉发送方的TCP有紧急数据要传送。于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而紧急数据后面的仍是普通数据,这时要与首部中的紧急指针字段配合使用。紧急指针指出了本报文段中的紧急数据的字节数,也就是指出了紧急数据的末尾位置在报文段的哪个地方。

2. 推送PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对     方的响应。在这种情况下,TCP就可以使用推送操作。这时,发送方就把该字段置1,并立即创建一个报文段发送       出去,接收方TCP收到PSH=1的报文段,就尽快地交付给接收应用进程,而不再等到整个缓存都填满了后再向上交     付。

二者的区别:

URG是把报文中的紧急数据放在整个报文的最前面,接收端接收到报文时先处理的是紧急数据,再处理的是后面的普通数据。PSH并不是等缓冲区满了才向上交付数据,而是一旦有紧急数据就尽快交付给了上层应用程序去处理。

二、TCP中的定时器

1.  连接建立(connection establishment)”定时器
     在发送SYN报文段建立一条新连接时启动。如果在75秒内没有收到响应,连接建立将中止。
 
2.“重传(retransmission)”定时器
       在TCP发送某个数据段时设定。如果该定时器超时而对端的确认还未到达,TCP将重传该数据段。重传定时器的值 (即TCP等待对端确认的时间)是动态计算的,与RTT的估计值密切相关,且还取决于该报文段已被重传的次数。
 
3.“延迟ACK(delayed ACK)”定时器
       在TCP收到必须被确认但无需马上发出确认的数据时设定。如果在200ms内,有数据要在该连接上发送,延迟的ACK响应就可随着数据一起发送回对端,称为捎带确认。如果200ms后,该确认未能被捎带出去,则定时器超时,此时需要发送一个立即确认。
 
4.“持续 (persist)”定时器
       在连接对端通告接收窗口为0,阻止TCP继续发送数据时设定。由于连接对端发送的窗口通告不可靠(只有数据才会被确认,ACK不会被确认),允许TCP继续发送数据的后续窗口更新有可能丢失。因此,如果TCP有数据要发送,但对端通告接收窗口为0,则持续定时器启动,超时后向对端发送 1字节的数据,判定对端接收窗口是否已打开。
 
5.“保活(keep alive)”定时器
       在TCP控制块的so_options字段设置了SOF_KEEPALIVE选项时生效。如果连接的连续空闲时间超过2小时,则保活定时器超时,此时应向对端发送连接探测报文段,强迫对端响应。如果收到了期待的响应, TCP可确定对端主机工作正常,在该连接再次空闲超过 2小时之前,TCP不会再进行保活测试。如果收到的是RST复位响应, TCP可确定对端主机已重启。如果连续若干次保活测试都未收到响应, TCP就假定对端主机已崩溃,但它无法区分是主机故障还是连接故障。
 
6. FIN_WAIT_2定时器
    当某个连接从FIN_WAIT_1状态变迁到FIN_WAIT_2状态并且不能再接收任何新数据时,FIN_WAIT_2定时器启动,设为10分钟。定时器超时后,重新设为75秒,第二次超时后连接被关闭。加入这个定时器的目的是为了避免如果对端一直不发送 FIN,某个连接会永远滞留在FIN_ WAIT_ 2状态(假设TCP不选用半打开功能)。
 
7. TIME_WAIT定时器
     一般也称为2MSL定时器。2MSL指两倍的MSL,即最大报文段生存时间。当连接转移到TIME_WAIT状态,即连接主动关闭时,定时器启动。连接进入TIME_WAIT状态时,定时器设定为1分钟,超时后,TCP控制块被删除,端口号可重新使用。

time_wait存在的原因有两点 :
1.可靠的终止TCP连接。 
2.保证让迟来的TCP报文段有足够的时间被识别并丢弃。

1.可靠的终止TCP连接,若处于time_wait的客户端发送给服务器确认报文段丢失的话,服务器将在此重新发送FIN报文段,那么客户端必须处于一个可接收的状态就是time_wait而不是close状态。 
2.保证迟来的TCP报文段有足够的时间被识别并丢弃,Linux中一个TCP端口不能打开两次或两次以上,当客户端处于time_wait状态时我们将无法使用此端口建立新连接,如果不存在time_wait状态,新连接可能会收到旧连接的数据。time_wait持续的时间是2MSL,保证旧的数据可以丢弃,因为网络中的数据最大存在MSL(maxinum segment lifetime)。


三、TCP的三次握手与四次挥手

1.   三次握手“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。我们来假设一种情况理解一下:

client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
关于TCP


2. 四次挥手:确保数据能够传输完成。

关闭连接时接收方和发送方共同的事,需要双方都发送请求并且确认与对方断开连接。关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

关于TCP