简单介绍
首先,这两个协议是传输层的协议,为应用进程提供端到端的逻辑通信,网络层(IP协议)是为主机之间提供的逻辑通信
为了使运行不同操作系统的计算机的应用进程能够通信,就必须用端口号进行标识
TCP协议
是传输层的协议,像应用层提供服务,是一种面向连接的协议,相当于一条可高信道,TCP叫做传输控制协议,
TCP传输的数据单位协议叫做TCP报文段
UDP协议
是一种面向无连接的协议,这种逻辑通信信道是一条不可靠的信道,UDP传输的数据单位协议叫做UDP报文或用户数据报
面向无连接,不需要建立连接,不适用拥塞控制,首部开销小,只有8个字节
只是在IP数据报服务之上增加了很少的功能,即端口的功能和差错检测,为什么不直接使用IP协议而使用UDP呢?就是因为IP进行的是IP地址到IP地址的传输,而每台计算机可能会有多个进程,到底是和哪一个进程通信就是通过端口区分的,端口就是一个进程
TCP、UDP协议的适用场景:
TCP一般用于文件传输(FTP HTTP 对数据准确性要求高,速度可以相对慢)
发送或接收邮件(POP IMAP SMTP 对数据准确性要求高,非紧急应用)
远程登录(TELNET SSH 对数据准确性有一定要求,有连接的概念)等等
UDP一般用于即时通信(QQ聊天 对数据准确性和丢包要求比较低,但速度必须快),在线视频(RTSP 速度一定要快,保证视频连续,但是偶尔花了一个图像帧,人们还是能接受的),网络语音电话(VoIP 语音数据包一般比较小,需要高速发送,偶尔断音或串音也没有问题)等等。
另外TCP可以用于网络数据库,分布式高精度计算系统的数据传输;UDP可以用于服务系统内部之间的数据传输,因为数据可能比较多,内部系统局域网内的丢包错包率又很低,即便丢包,顶多是操作无效,这种情况下,UDP经常被使用。
UDP报文格式:

TCP报文首部格式:

数据偏移(即首部长度)——占 4 位,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。
保留字段——占 6 位,保留为今后使用,但目前应置为 0。
源端口和目的端口字段——各占 2 字节。端口是运输层与应用层的服务接口。运输层的复用和分用功能都要通过端口才能实现。
序号字段(seq)——占 4 字节。TCP 传送的数据流中的每一个字节都编上一个序号。seq值则指的是本报文段所发送的数据的第一个字节的序号。
确认号字段(ACK)——占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。
紧急 URG —— 当 URG = 1 时,表示紧急字段,应尽快传送,优先级较高的数据。
确认 ACK —— 只有当 ACK =1 时确认号字段才有效。当 ACK =0 时,确认号无效。
推送 PSH (PuSH) —— 接收 TCP 收到 PSH = 1 的报文段,就立马交给应用程序,而不需要等待缓存 存满在交付;
复位 RST (ReSeT) —— 当 RST =1 时,表明 TCP 连接中出现严重错误,例如主机宕机,必须释放连接,然后再重新建立连接。
同步 SYN —— 同步 SYN = 1 ,表示这是一个连接请求或接受报文。
终止 FIN (FINis) —— 用来释放一个连接。FIN =1 表明此报文段的发送端的已发送完毕数据,并要求释放运输连接。
TCP/IP的三次握手和四次挥手
TCP的三次握手:
TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式和表情的表现 相互确定对方是否认识自己。
张三首先向李四招手(SYN = 1,seq=x),此时他处于syn_sent状态,李四看到张三想自己招手,此时处于syn_rcvd状态,然后点了点头挤出了一个微笑(ACK=1,ack=x+1),张三看到李四确认看到了他所以此时张三处于 estalished状态;
而此时李四比较怀疑,他看到我了吗,于是李四向张三招了招手(SYN=1,seq=y),张三此时看到李四向自己招手,于是向李四微笑 示意了一下(ACK=1,ack = y+1,seq = x+1),李四看到张三想自己微笑后于是就处于estalished状态;
我们看到有两个中间状态,syn_sent和syn_rcvd,这两个状态叫着「半打开」状态,就是向对方招手了,但是还没来得及看到对方的点头微笑。syn_sent是主动打开方的「半打开」状态,syn_rcvd是被动打开方的「半打开」状态。客户端是主动打开方,服务器是被动打开方。

此时三次连接建立成功:
下来进行的是数据传输:
张三喊了一句话data,李四听到之后要向张三回复收到(ACK),如果张三等了好久还没有等到李四的回复,这就是tcp重传,也有可能是李四回复的ack张三 没有听到,此时也会 重传 ,既然会重传 有可能就导致李四一句话重复听了几遍,此时就要去重。
张三有可能喊了好多句话data,而此时李四只需要回复一次,这就是批量ACK
但是有可能张三一下 说了好多话,而李四回复不过来,这就是TCP的滑动窗口,提前需要设定好发送和接收速率
传输的过程中可能因为网际路由而导致出现数据包乱序的情况,操作系统网络内核会对数据包进行排序,以致于最终到达用户层的数据是一致的。
TCP滑动窗口示意图

如果A的可用窗口为0,此时还没有收到确认信号,此时必须停止发送
此时会存在发送缓存和接收缓存
发送缓存:应用程序准备发送给发送方的TCP数据和用来存放已发送但未收到确认的数据
接收缓存:用来存放按序到达但未被应用程序读取的数据和乱序的数据

数据传输完成后的四次挥手:
此过程和连接过程类似,张三挥手(FIN=1,seq=u),此时处于fin_wait_1,李四看到了向张三伤感的微笑(ACK=1,ack = u+1,seq = v),处于close_wait,此时张三处于fin_wait_2状态,李四挥手(FIN=1,seq = w),此时处于last_ack,张三看到李四挥手,张三看到后伤感的微笑(ACK=1,ack = w+1,seq = u+1),此时张三处于time_wait状态,李四收到张三的ACK后处于,closed状态;
处于time_wait状态的张三,此时处于的时间大概在4min(2MSL),此时并不能释放套接字资源,要等到李四确认收到ACK,李四如果没有收到ACK,他会进行fin重传,处于time_wait状态的张三会立马进行ack重传,如果重传的报文都收到了,而之前的报文此时传过去 ,会采取立刻清楚。
如果李四不发送 fin时,也可以中断连接,此时直接进入time_wait状态



以上是基本原理
常见面试问题:
1.为什么三次握手 不是二次?
答:比如张三发送了SYN = 1 ,seq = x ;李四 此时回复ACK = 1 ,ack = x +1 ,seq = y;此时就表示连接已建立;表明只要张三收到 李四的ACK后连接就建立了。
假设有个场景,张三发送的连接请求报文段滞留了,延迟了,而李四一直未收到,会导致张三未收到李四的ACK确认序号,所以他会重传,最终收到了李四的ACK而建立了连接;但是长时间后张三而没有 主动发起请求,而之前滞留的报文被李四收到了,那么李四就会回复ACK,而张三没有 数据可发,此时会 导致李四的资源大量浪费,而三次握手就会解决这种情况李四没有收到张三的ACK时就不会建立连接;
2.为什么连接的时候是三次握手,关闭的时候却是四次挥手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
本文深入解析TCP和UDP两种传输层协议的区别与联系,探讨它们如何为应用进程提供端到端的逻辑通信,以及各自适用的不同场景。同时,还详细解释了TCP三次握手和四次挥手的过程。
360

被折叠的 条评论
为什么被折叠?



