【网络基础】TCP/UDP

1,TCP和UDP区别

TCP协议面向连接的协议,提供稳定的双向通信,需要经过“三次握手”才能建立连接;为了提供稳定的数据传输功能,提供了超时重传机制,具有较高的稳定性。
UDP是无连接的,提供不稳定的单向通信功能,当然UDP也可以实现双向通信功能。虽然效率更高,但不能保证数据一定能够正确传输,尤其在网络拥塞的情况下。

1)区别

①TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
②TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
③TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
④每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
⑤TCP首部开销20字节;UDP的首部开销小,只有8个字节
⑥TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

2,TCP三次握手(three-way handshake)和四次分手

TCP用三次握手(three-way handshake)过程创建一个连接,使用四次分手 关闭一个连接。因为TCP是全双工模式,所以四次分手的目的就是为了可靠地关闭连接。
三次握手与四次分手的流程如下所示:
三次握手和四次分手

1)两个序号和三个标志位:

①序号

seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

②确认序号

ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。
确认方ack=发起方req+1,两端配对。

③标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:

(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。表示已经没有数据 需要发送了。

2)三次握手

①第一次握手:建立连接。

客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;

②第二次握手:服务器收到SYN报文段。

服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

③第三次握手:客户端收到服务器的SYN+ACK报文段。

然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态(已建立状态),完成TCP三次握手。 完成了三次握手,客户端和服务器端就可以开始传送数据。

④第三次握手的必要性

三次握手可以保证任何一次握手的失败都是可感知的,不会浪费资源。
否则,对于两次握手:A发送建立连接,B确认后就建立连接;在网络延迟的情况下,A第一次发送建立连接,B未响应,A第二次又发送建立连接,B建立连接。传输完成后关闭连接,当A第一次延迟的建立连接请求发送到B时,B建立连接,并且一直等待A发送数据,但对于A来说,连接已经关闭了。这样就造就了B一直在等待发送数据。
对于三次握手,A请求建立连接,B建立连接,A确认建立连接。A如果长时间未确认建立连接,B就会关闭连接。

⑤为什么不是四次握手

如果四次,那么就造成了浪费,因为在三次结束之后,就已经可以保证A可以给B发信息,A可以收到B的信息; B可以给A发信息,B可以收到A的信息。

⑥握手失败

第一次握手A发送SYN传输失败,A,B都不会申请资源,连接失败。如果一段时间内发出多个SYN连接请求,那么A只会接受它最后发送的那个SYN的SYN+ACK回应,忽略其他回应全部回应,B中多申请的资源也会释放

第二次握手B发送SYN+ACK传输失败,A不会申请资源,B申请了资源,但收不到A的ACK,过一段时间释放资源。如果是收到了多个A的SYN请求,B都会回复SYN+ACK,但A只会承认其中它最早发送的那个SYN的回应,并回复最后一次握手的ACK

第三次握手ACK传输失败,B没有收到ACK,释放资源,对于后序的A的传输数据返回RST。实际上B会因为没有收到A的ACK会多次发送SYN+ACK,次数是可以设置的,如果最后还是没有收到A的ACK,则释放资源,对A的数据传输返回RST

3)四次分手

收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。

①第一次分手:表示主机1没有数据要发送给主机2了。

主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;

②第二次分手:主机2告诉主机1,我“同意”你的关闭请求。

主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;

③第三次分手:请求关闭。

主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;

④第四次分手:正常关闭。

主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。

⑤为什么分手比握手多一次

A给B发送FIN报文段,表示A没有数据发给B,但是B可能还有数据发给A。所以需要多确认一次。

3,TCP如何保证数据传输的可靠性?

1)确认和重传

接收方收到报文后就会进行确认,发送方一段时间没有收到确认就会重传。(见TCP重传机制)

2)数据校验

数据合理分片与排序,TCP会对数据进行分片,接收方会缓存为按序到达的数据,重新排序后再提交给应用层。

3)流程控制

当接收方来不及接收发送的数据时,则会提示发送方降低发送的速度,防止包丢失。

4)拥塞控制

当网络发生拥塞时,减少数据的发送。

4,TCP重传机制

传输过程中发生丢包,则需要使用重传机制。

1)超时重传机制(RTO)

在请求包发出去的时候,开启一个计时器,当计时器达到时间之后,没有收到ACK,就进行重发请求的操作,一直重发直到达到重发上限次数或者收到ACK。
例如:接收端给发送端的Ack确认只会确认最后一个连续的包,比如,发送端发了1,2,3,4,5一共五份数据,接收端收到了1,2,于是回ack 3,然后收到了4(注意此时3没收到),此时的TCP会怎么办?等待发送端的ACK 3,直到超时后,就会再发送3。
面临问题,重传是重传#3呢还是重传#3,#4,#5呢?

2)快速重传机制(Fast Recovery)

当接收方收到的数据包是不正常的序列号,那么接收方会重复把应该收到的那一条ACK重复发送,这个时候,如果发送方收到连续3条的同一个序列号的ACK,那么就会启动快速重传机制,把这个ACK对应的发送包重新发送一次。
例如:如果发送方发出了1,2,3,4,5份数据,第一份先到送了,于是就ack回2,结果2因为某些原因没收到,3到达了,于是还是ack回2,后面的4和5都到了,但是还是ack回2,因为2还是没有收到,于是发送端收到了三个ack=2的确认,知道了2还没有到,于是就马上重转2。然后,接收端收到了2,此时因为3,4,5都收到了,于是ack回6。
同样面临问题:是重传#2呢还是重传#2,#3,#4,#5呢?

①不启用sack的reno式重传

②sack重传

5,TCP阻塞

1)慢启动

当一个连接连接上网络的时候,并不应该一次向网络中就发送大量的数据包,否则的话,如果网络链路状况不是很好的情况,这些网络包可能会加重网络拥堵的情况。所以最初TCP连接建立之后,发送网络包的大小是逐渐增长的,最开始是1个最大报文大小,然后是指数级增长。这个就是慢启动机制。

但是到了一个数值,就不能再进行指数增长了,这个时候,网络包增长就从指数增长改成线性增长,就是一次增加一个MSS。这个就是拥塞避免阶段。

2)Nagle算法

如果每个网络传输都只传输一个小包,会浪费资源,增加拥堵。糊涂窗口综合症就是发送方和接收方糊里糊涂达成的协商是传送小包。

为了解决这个问题,很多方法应运而生,Nagle算法就是其中一个方法。

Nagle算法规定了,发送方网络链路上一个连接只能有一个未获得ACK的请求包。这个就意味着,发送方只有等待上一个请求的ACK回来之后才能发送下一个请求,这样两个请求过程中间,发送方的缓存区就存储了足够滑动窗口大小的包进行传递,这样就有效避免了大量的小包产生。

3)Cork算法

另外一种解决糊涂窗口综合症的方法就是Cork算法。这个算法比Nagle算法更激进一些,直接计算出一个值,当发送方的滑动窗口大小小于这个值的时候,不进行数据包的发送。这样这个算法就能有效直接杜绝小包的出现了。当然可能会导致数据有一定的延迟性了。

Nagle和Cork算法都是在发送方进行控制,两个算法的着重点不同,Cork算法着重点在于避免小包,更多是端到端的优化。Nagle算法则是为了提高网络的利用率。

4)延迟ACK

延迟ACK算法是从接收方防止糊涂窗口综合症。
接收方并不是收到请求之后立刻发送ACK,而是开启一个计时器,等到计时器结束的时候,才发送ACK。或者是接收方在需要回发送请求的时候,顺带着把上个请求的ACK发送回去了。这个机制如果配合Nagle算法,能让连接的滑动窗口达到一个预期的比较好的值。

猜你喜欢

转载自blog.csdn.net/sunshinetan/article/details/81030987