TCP:
1、概念:
TCP(Transmission Control Protocal传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP工作在网络OSI七层模型中的第四层-----传输层。
TCP的可靠性在于:
1)TCP是基于序号请求、确认机制(应答机制----一请求一应答);
2)TCP是面向连接的全双工的面向字节流服务;
3)基于序号丢包机制,确保数据按序到达,确保丢包问题;
4)基于序号丢包问题,会重发数据;
5)基于滑动窗口进行流量控制‘
6)TCP体现在数据出现大面积丢包时,不应该重传,可以不发或者少发;
7)TCP当中会维护多种定时器,通过定时器完成定时任务,确保它的可靠性。
2、TCP三次握手:
所谓三次握手(three-way-handshake),是建立在一个TCP连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是:链接服务器指定端口,建立TCP链接,并同步链接双方的序列号和确认号并交换TCP窗口大小信
息。客户端和服务器分别发送了连接请求,也答应了对方的连接请求,其中服务器的请求和应答在一个段中发出,一
次一共有三个段用于建立连接,称为”三次握手”。在socket编程中,客户端执行connect()时,会触发三次握
手。
TCP的六种标志位:URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
1)URG:紧急指针(urgent pointer)有效,一旦被设置,其后16位标志位有效;
2)ACK:确认序号有效,被设置为有效后,认为是确认报文;
3)PSH:接收方应该尽快将这个报文交给应用;
4)RST:重置连接,应用场景:1.长时间不能访问聚会被RST;2.连接建立失败时会被RST;
5)SYN:同步标志位,发起一个新连接;
6)FIN:释放一个连接。
三次握手的过程:
第一次握手:建立连接时,服务器发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即可
SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服
务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始发送数据。
一个完整的三次握手就是:请求----应答----再次确认
3、TCP四次挥手:
TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way-handshake)。客户端或者服务器均可主动发
起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
四次挥手:
由于TCP链接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发
送一个FIN来种植这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后
任然发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送;
(2)服务器B收到这个FIN,它发挥一个FIN给客户端A;
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A;
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1.
5、为什么需要“三次握手”?
了服务端,因而产生错误”。在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在
延迟的重复分组”的问题。这两种不用的表述其实阐明的是同一个问题。
谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发
出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间
才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次
发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要
server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也
不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多
资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的
确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。主要目的防止server端一直等待,
浪费资源。
6、为何要四次挥手呢?
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
7、为什么建立连接协议是三次握手,而关闭连接时是四次挥手?这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以吧ACK和SY
N(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通
知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你不可以马上关闭SO
CKET,也即你可能还需要发送一些数据给对方之后,在发送FIN报文给对方来表示你同意现在可以关闭连接
了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
8、TIME_WAIT
根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态。
TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒。TIME_WAIT状态
下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,
将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影
响服务器的处理能力,甚至耗尽可用的socket,停止服务。
为什么需要TIME_WAIT?
TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑
保证。
主动发起关闭连接的操作的一方将达到TIME_WAIT状态,而且这个状态要保持Maximum Segment Lifetime的两
倍时间。为什么要这样做而不是直接进入CLOSED状态?
原因有二:
一、保证TCP协议的全双工连接能够可靠关闭
二、保证这次连接的重复数据段从网络中消失
先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收
Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发
的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情
况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是
要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。
再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连
接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有
特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这
些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接
的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生
混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。