互联网协议(5)——TCP&UDP

物理层完成了计算机的物理连通,链路层和网路层解决了主机对主机的正确通信问题,那么新的问题来了,一个主机上可能运行着多个程序,都在收发数据,如何判断数据是对应于哪一个程序的呢?传输层就是来完成这个信息管理工作的。因此也需要新的协议来标定主机上同时运行的多个程序。在传输层里,我们称这个标定叫做端口。主机IP和端口联合在一起可以唯一定位一个程序,也就是真正的数据收发者了。

完成这一工作的是UDP协议(User Datagram Protocol)和TCP协议(Transmission Control Protocol )。

两种传输协议

TCP

TCP是面向连接的,可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管道中的水流。当应用程序采用TCP发送消息是,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。

TCP还提供可靠性传输,实行“顺序控制”和“重发控制”机制。此外还具备“流量控制”,“拥塞控制”,提高网络利用率等众多功能。

UDP

UDP是不具有可靠性的数据包协议。细微的处理会交给上层的应用来完成。在UDP情况下,虽然可以保证消息发送,但不能保证消息一定会到达。因此,应该有时会根据自己的需求进行重发处理。

TCP和UDP的区别和适用场景

TCP是可靠的传输协议,UDP不具备可靠性。
TCP具有顺序控制,重发控制等高等功能。UDP简单所以更快速。
UDP适合于

包总量较少的通信;
即时通信;
特定网络通信;
广播通信。

TCP高级功能

连接控制:

TCP是面向连接的流协议,因此在真正通信前后要建立和断开连接。无论建立还是断开都要进行反复的确认。

这里写图片描述
这里写图片描述

建立连接:

在建立连接的时候,客户端首先向服务器申请打开某一个端口(用SYN段等于1的TCP报文),然后服务器端发回一个ACK报文通知客户端请求报文收到,客户端收到确认报文以后再次发出确认报文确认刚才服务器端发出的确认报文(绕口么),至此,连接的建立完成。这就叫做三次握手。如果打算让双方都做好准备的话,一定要发送三次报文,说多不多,说少不少。

再加上TCP的超时重传机制,那么TCP就完全可以保证一个数据包被送到目的地。

结束连接:

TCP有一个特别的概念叫做half-close,这个概念是说,TCP的连接是全双工(可以同时发送和接收)连接,因此在关闭连接的时候,必须关闭传和送两个方向上的连接。客户机给服务器一个FIN为1的TCP报文,然后服务器返回给客户端一个确认ACK报文,并且发送一个FIN报文,当客户机回复ACK报文后(四次握手),连接就结束了。

客户机状态转移:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

服务器状态转移:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

最大报文长度:

对于大的数据,TCP需要分包传送,在一个稳定的连接中以多大长度来分包是需要连接双方协商决定的,在建立连接过程中,SYN会将客户端可以使用的报文长度发送给服务器,服务器把自己的可行的报文长度再跟随第二次握手传给客户端,这样选择一个两者共同的最大值作为报文长度,即最大报文长度(Maximum Segment Size)。

PS:共同的最大值不是取max,而是客户端和服务器各自有几个可行的报文长度取值,是有限几个值,然后取它们的交集中的最大值。

2MSL等待状态:

在FIN_WAIT2发送了最后一个ACK数据报以后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束,但是,问题也来了。

由于插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。

FIN_WAIT_2状态
这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于CLOSE_WAIT状态,而直到应用层来决定关闭这个状态。

窗口

当建立好连接之后,数据开始分包传输,对于每一个数据包,TCP都需要进行接收确认,确认的方法是接收端向发送端发送它希望得到的下一个数据包的数据流位置。例如一个1—10000的数据流,按1000为一段传输,接收端收到1-1000的段之后,会向发送端返回一个包含1001的信号,说明1-1000收到了,下面需要1001-2000。这样就时每个数据包的传输都有了确认。

但问题也就来了,这样太慢了!每一个包都要确认,在接受到确认之前发送端需要等待,这样浪费了发送和接收端的性能,所以就有了窗口控制。

窗口就是:无需等待确认而可以继续发送数据的最大值。

即发送端可以在窗口范围内发送多条数据报,而不需要确认。发送端将需要发送的数据存储于缓存中,开始发送,然后逐渐接收到确认的回复,每收到一条确认,就可以把这条对应的数据从缓存中清除,然后加载新的数据到缓存,而如果没有收到确认,就会使用缓存中的数据进行重发。发送端始终保持着缓存中持有着一定量的数据,随着数据确认接收进行更新,这就是窗口滑动。

窗口控制与重发控制:

窗口控制:
接收方——>发送方返回确认信息丢失的情况

在有了窗口基础上,如果接收方到发送方的确认信息丢失,只要能够得到后续的确认信息,会以最后的确认信息为准而无需发送之前的信息,因为接收方只有收到之前的信息才会允许确认信息的待接收数据编号,如果之前的信息没有收到,则涉及到重发控制。

重发控制:

发送方——>接收方发送数据丢失的情况

如果信息没有到达接收端,则接收端的待接收数据编号不会更新,就会一直重复发送之前的编号给发送端,当发送端收到三次同样的信号,就认定数据没有传送成功,将重新发送。

流控制

发送端根据接收端的实际接收能力控制发送的数据量:
将接收端缓冲区剩余量发送给发送端作为窗口大小。
避免造成重发,浪费带宽。

拥塞控制

慢启动:
拥塞窗口:慢启动过程中窗口的数据长度,从1个最大报文长度开始逐渐增长,每接收到一个确认信息就增加一个最大报文长度。
实际窗口宽度=min{拥塞窗口,主机接收窗口}

慢启动阈值:
窗口逐渐扩大,但1-2-4-8这样的增长速度太快,到了一定值可能发生拥堵从而造成确认信息超时,当发生超时,就将拥塞窗口降到当前的一半,并把它作为阈值threshold,之后的窗口增长变为每次接到确认,增长1/threshold报文长度,这会导致每次增长可能不到一个最大报文长度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值