目录
在学习TCP/UDP之前先来了解以下整体的通信传输,它是一个向下封装、向上分用的过程:
这是TCP/IP四层模型,所以要想实现通讯,通过TCP建立和断开连接是至关重要的,图中的每一层都不可或缺。
TCP,即传输控制协议,就是对数据的传输进行一个详细的控制。
·源/目的端口号:表示数据从哪个进程来,到哪个进程去;
·6位的标志位:常用的:ACK(确认号是否有效)、SYN(请求建立连接)、FIN(通知对方,本端要关闭)
....
TCP对数据传输提供管控机制,主要体现在两个方面:安全和效率。
这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率。
①确认应答机制(安全机制)
每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发数据。
②超时重传机制(安全机制)
主机A发送数据给主机B后,可能因为网络拥堵等原因,数据无法到达主机B,如果主机A在一个特定的时间间隔内未能收到主机B的确认应答,就会重新发送。
但也可能是因为ACK丢包了,此时间隔一段时间后重新发送也不会导致数据重复,因为它可以利用前面的序列号,很容易就做到去重的效果。
超时时间如何确定?
TCP为了保证无论任何环境下都能比较高性能的通信,因此会动态地计算这个最大超时时间:超时以500ms为一个单位进行控制,之后每次判定超时重发时间都是500ms的整数倍。比如第一次重发前等待500ms,若是仍无响应,下一次重传等待时间就为2*500ms。
③连接管理机制(安全机制)
在正常情况下,TCP都要经过三次握手建立连接,四次挥手断开连接。
三次握手建立连接
为什么需要三次握手?
为了防止已经失效的连接请求突然又传送到了服务器端,因而产生错误。
比如:客户端发出的第一个连接请求并没有丢失,而是在某个网络节点长时间滞留了,以至于先前的连接释放以后的某个时间才到达服务器端。本来这是一个早已失效的请求,但是服务器端接收到以后,就会误以为是新的连接请求,于是就向客户端发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要服务器端发出确认,新的连接就建立了,由于此时客户端已经没有了连接请求,因此不会理睬服务器端的确认,也不会向服务器端发送数据,但此时服务器端却以为新的连接已经建立,并且一直等待客户端发来数据。所以没有采用“三次握手”,这种情况下服务器端的很多资源就白白浪费掉了。
类比打电话的过程:
张三:喂?李四你能听到我说话吗?
李四:喂?我能听到,你能听到我说话吗?
张三:我能听到,我们开始对话吧。
李四:好!
四次挥手断开连接
为什么需要四次挥手呢?
TCP是全双工模式(双向通信),当client发出FIN报文段时,只是表示client已经没有数据要发送了,client告诉server,它的数据已经全部发送完毕了;但是,这个时候client还是可以接受来server的数据;当server返回ACK报文段时,表示它已经知道client没有数据发送了,但是server还是可以发送数据到client的;当server也发送了FIN报文段时,这个时候就表示server也没有数据要发送了,就会告诉client,我也没有数据要发送了,如果收到client确认报文段,之后彼此就会愉快的中断这次TCP连接。
与“三次挥手”一样,在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性,一旦出现某一方发出的TCP报文丢失,便无法继续"挥手",以此确保了"四次挥手"的顺利完成。
单工、半双工、全双工:(184条消息) 单工,半双工,全双工区别以及TDD和FDD区别_路漫远吾求索的博客-CSDN博客_tdd是全双工还是半双工
④滑动窗口机制(效率机制)
上面我们讨论了确认应答机制,对于每发送的一个数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段。这样传输就是性能比较差。既然一发一收的性能较低,那我们可以一次发送多条数据,就可以大大提高性能(实际上就是将多个等待时间重叠到一起)
滑动窗口的两个问题:
问题一:数据包已经到达,但是ACK被丢了
这种情况,部分ACK丢了不要紧,因为可以通过后续的ACK进行确认。
问题二:数据包直接丢了
比如:1-1000数据发送正常,而1001-2000的数据包丢了,这时发送端会一直接收到”下一个是1001“的ACK,就像在提醒发送端”我想要的是1001“,如果发送端主机连续三次收到了同样的ACK,它就会重发丢包字段。
⑤流量控制机制(安全)
接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端缓冲区被打满,这个时候发送端继续发送,就会造成丢包,继而引起丢包重传等一系列连锁反应。
因此TCP根据自己处理能力,来决定发送端的发送速度。接收端将自己可以接收的缓冲区大小放入TCP首部中的”窗口大小“字段中,通过ACK端通知发送端。
⑥拥塞控制机制(安全)
虽然TCP有了滑动窗口这个机制来提高性能,但是因为网络上有很多计算机,可能当前的网络状态就已经比较拥堵。在不清楚网络状况的情况下,贸然发送大量数据,是很有可能雪上加霜的。
TCP引入了慢启动机制:先发送少量的数据,探探路,摸清情况后,再决定按照多大的速度传输数据。
定义一个初始拥塞窗口为1,每次收到ACK,拥塞窗口加1,每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口进行对比,取较小的作为实际发送窗口,为了不增长那么快,引入了一个慢启动的阈值,当超过这个阈值的时候,不再按照指数式爆炸增长,而是线性方式增长。当TCP开始启动的时候慢启动阈值等于窗口最大值,在每次超时重传后,慢启动阈值变为原来的一半,同时拥塞窗口置为1。
拥塞控制归根结底就是TCP协议想尽可能快的把数据传输给对方,但又要避免给网络造成太大的压力的一种折中方案。
⑦延迟应答机制(效率机制)
假设接收端缓冲区为1M。一次收到了500K的数据,如果立即应答,返回的窗口大小就是500K;但实际上可能处理端处理速度极快,10ms之内就把500K数据从缓冲区消费掉了,如果接收端稍微等一会儿再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M。
⑧捎带应答机制(效率机制)
在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是”一发一收“。意味着客户端给服务器说了”hello“,服务器端也会给客户端回个”hi“;那么这个时候ACK就可以搭顺风车,和服务器回应信息一起回到客户端。
2.1 UDP特点
无连接:知道对端的IP和端口号直接进行传输,不需要建立连接。
不可靠:没有任何安全机制,发送端发出数据报后,如果因为网络故障该段无法发到对方,UDP协议也不会返回任何消息。
面向数据报:原样发送
只有接收缓冲区,没有发送缓冲区。