TCP/UDP协议都工作在传输层
这两个协议的目标都是在程序之间传输数据(可以是文本文件、图片、视频),对于TCP协议和UDP协议来说,都是一堆二进制数。
把人与人之间的通信看成是进程间通信,“写信”是基于非连接的UDP,“打电话”是基于连接的TCP。
一、TCP
TCP保证数据传输过程有三个关键步骤:
-
三次握手
建立连接的过程:
1.1 客户端向服务端发起连接请求时先发送一包连接请求数据(SYN包)
1.2 服务端同意连接请求发送一包(SYN+ACK包)
1.3 客户端收到之后回复一包ACK包,此过程中客户端和服务端之间互相发送了三包数据,称为三次握手之所以三次握手而不是两次握手,在服务端回复完SYN+ACK之后就建立连接是为了防止因为已失效的请求报文突然又上传到服务器引起的错误,三次握手本质上是为了解决网络信道不可靠的问题,为了在不可靠的信道上建立可靠的连接。
-
传输确认
一包数据可能被拆成多包发送,可能产生丢包问题;数据包到达的先后顺序不同,可能产生乱序问题。
为了解决丢包问题和乱序问题,TCP为每个连接都建立了一个发送缓冲区,从建立连接后的第一个字节序列号为0,后面每个字节的序列号加一。
发送数据时从发送缓冲区取一部分数据组成发送报文,在报文的TCP协议头中附带序列号和长度,接收端收到数据后需要回复确认报文,确认报文中的ACK=接收序列号+长度。(也就是下一包数据的起始序列号)
这样一问一答的发送方式,能让发送端确认发送的数据已经被接收端收到,发送端也可以一次发送连续的多包数据,接收端只需要回复一次ACK就可以。
这样发送端可以把待发送数据分割成一系列碎片片发送到接收端,接收端根据序列号和长度,在接收后重构出完整的数据。
若其中丢失了某些数据,接收端可以要求发送端重传。
如丢失了100-199这100个字节,接收端向发送端发送ACK=100的报文,发送端收到后重传这一包数据,接收端进行补齐。
以上过程不区分客户端和服务端,TCP连接是全双工的,对于两端来说均采用以上机制。
-
四次挥手
处于连接状态的客户端和服务端都可以发送关闭连接请求,需要四次挥手进行连接关闭。
如客户端主动发起连接关闭请求,会向服务器端发送一包FIN包,客户端进入终止等待1状态,这是第一次挥手。
服务端收到FIN包,发送一包ACK包表示自己进入关闭等待状态,客户端进入终止等待2状态,这是第二次挥手。
服务端此时还可以发送未发送的数据,客户端还可以接收数据,等待服务端发送完数据之后,发送一包FIN包,进入最后确认状态,这是第三次挥手。
客户端收到之后回复ACK包,进入超时等待状态,经过超时时间之后关闭连接。服务端收到ACK包之后立即关闭连接。这是第四次挥手。
客户端之所以要等待超时时间,是为了保证对方已经收到ACK包。
因为假设客户端发送完最后一包ACK包之后就释放了连接,一旦ACK包在网络中丢失,服务端将一直停留在最后确认状态。
若客户端发送最后一包ACK包之后,等待一段时间,这时服务端会因为没收到ACK包而重发FIN包,客户端会响应FIN包,重发ACK包并刷新超时时间。
四次挥手机制也是为了在不可靠的网络链路中进行可靠的连接断开确认。
二、UDP
UDP协议是基于非连接的
发送数据就是把数据包简单封装一下,然后从网卡发出去就可以,数据包之间没有状态上的联系,UDP处理方式简单,所以性能损耗非常少,对于CPU、内存资源的占用远小于TCP,但是对于网络传输过程中产生的丢包,UDP协议并不能保证,UDP传输稳定性上弱于TCP。
TCP传输数据稳定可靠,适用于对网络通讯质量要求较高的场景,如传输文件、发送邮件、浏览网页。
UDP速度快,但可能产生丢包,适用于对实时性要求高、对少量丢包没有太大要求的场景,如域名查询、语音通话、视频直播。
UDP还有一个很重要的应用场景:隧道网络,比如常用的VPN就是一种隧道网络及在SDN中用到的VXLAN也是一种隧道网络。