前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP、UDP 的区别,三次握手、四次挥手

TCP、UDP 的区别,三次握手、四次挥手

原创
作者头像
Krry
修改2019-03-04 10:37:01
2.8K0
修改2019-03-04 10:37:01
举报
文章被收录于专栏:KrryblogKrryblog

博客地址:https://ainyi.com/55

TCP、UDP 的区别总结

|TCP|DUP|

|-|-|-|

|TCP 面向连接(如打电话要先拨号建立连接)|UDP 是无连接的,即发送数据之前不需要建立连接|

|TCP 提供可靠的服务。(通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达)|UDP 尽最大努力交付,即不保证可靠交付|

|TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流|UDP 面向报文|

|TCP 拥塞控制|UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等)|

|每一条 TCP 连接只能是点到点的|UDP 支持一对一,一对多,多对一和多对多的交互通信|

|TCP 首部开销20字节|UDP 的首部开销小,只有8个字节|

|TCP 的逻辑通信信道是全双工的可靠信道|UDP 则是不可靠信道|

|TCP 传输速率:慢|UDP 传输速率:快|

TCP/IP 五层模型

HTTP状态码:

100-199:表示信息性代码,标示客户端应该采取的其他动作,请求正在进行。

200-299:表示客户请求成功。

300-399:表示用于已经移走的资源文件,指示新的地址。 重定向

400-499:表示由客户端引发的错误。

500-599:表示由服务器端引发的错误。

404 没找到页面(not found)

403 禁止访问(forbidden)

200 一切正常(ok)

302/307 临时重定向

301 永久重定向

304 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改)从缓存中读取

三次握手

指的是在发送数据的准备阶段,服务器端和客户端之间需要进行三次交互

OSI 参考模型中的网络层,在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。(TCP在运输层,IP在网络层)

  • 第一次握手:建立连接时,客户端发送 syn 包(syn=j) 到服务器,并进入 SYN_SEND 状态,等待服务器确认;
  • 第二次握手:服务器收到 syn 包,必须确认客户的 syn(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;
  • 第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手;

通俗的说

  • 第一次握手:A(客户端):你好我是A,你听得到我在说话吗(发送建立连接请求,等待服务器确认) A->SYN_SEND
  • 第二次握手:B(服务端):听到了,我是B,你听到我在说话吗(确认客户端的请求,同时自己也发送一个请求) B->SYN_RCVD | A->ESTABLISHED
  • 第三次握手:A(客户端):嗯,听到了(确认服务端的请求,发送完毕,建立连接) B->ESTABLISHED   建立连接,开始聊天!

可能会有这种想法,为什么要进行三次握手才能建立连接,两次貌似也可以,事实三次握手是可靠的的连接过程

三次握手的目的

三次握手的目的是 “为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误“,

“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。

假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于是client发送的请求报文段滞留后才到达服务端,而现在client并没有发出新的建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。

采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

四次挥手

当客户服务端传输完毕,需要终止连接的时候,就会进行四次挥手

由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN 只意味着这一方向上没有数据流动,一个 TCP 连接在收到一个 FIN 后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭

  • 第一次挥手:TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送
  • 第二次挥手:服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
  • 第三次挥手:服务器关闭客户端的连接,发送一个FIN给客户端
  • 第四次挥手:客户端发回ACK报文确认,并将确认序号设置为收到序号加1

通俗的说

  • 第一次挥手:A(主机1):喂,我不说了,我听你说最后的话(只能接收)。 A->FIN_WAIT1
  • 第二次挥手:B(主机2):我知道了。等下,我还没说完。Balabala….. B->CLOSE_WAIT | A->FIN_WAIT2
  • 第三次挥手:B(主机2):好了,说完了,我也不说了。 B->LAST_ACK
  • 第四次挥手:A(主机1):表示已收到。 A->TIME_WAIT | B->CLOSED A等待 2MSL,保证B收到了消息,否则A又要表达一次收到了 A->CLOSED

各个状态的含义如下

太长,不建议看,哈哈哈哈~~~

CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”。

LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接。

SYN_RCVD :表示接收到了SYN报文。在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat很难看到这种状态,除非故意写一个监测程序,将三次TCP握手过程中最后一个ACK报文不予发送。当TCP连接处于此状态时,再收到客户端的ACK报文,它就会进入到ESTABLISHED 状态。

SYN_SENT :这个状态与SYN_RCVD 状态相呼应,当客户端SOCKET执行connect()进行连接时,它首先发送SYN报文,然后随即进入到SYN_SENT 状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT 状态表示客户端已发送SYN报文。

ESTABLISHED :表示TCP连接已经成功建立。

FIN_WAIT_1 :这个状态得好好解释一下,其实FIN_WAIT_1 和FIN_WAIT_2 两种状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:- FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET进入到FIN_WAIT_1 状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2 状态。当然在实际的正常情况下,无论对方处于任何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1 状态一般是比较难见到的,而FIN_WAIT_2 状态有时仍可以用netstat看到。

FIN_WAIT_2 :上面已经解释了这种状态的由来,实际上FIN_WAIT_2状态下的SOCKET表示半连接,即有一方调用close()主动要求关闭连接。注意:FIN_WAIT_2 是没有超时的(不像TIME_WAIT 状态),这种状态下如果对方不关闭(不配合完成4次挥手过程),那这个 FIN_WAIT_2 状态将一直保持到系统重启,越来越多的FIN_WAIT_2 状态会导致内核crash。

TIME_WAIT :表示收到了对方的FIN报文,并发送出了ACK报文。 TIME_WAIT状态下的TCP连接会等待2*MSL(Max Segment Lifetime,最大分段生存期,指一个TCP报文在Internet上的最长生存时间。每个具体的TCP协议实现都必须选择一个确定的MSL值,RFC 1122建议是2分钟,但BSD传统实现采用了30秒,Linux可以cat /proc/sys/net/ipv4/tcp_fin_timeout看到本机的这个值),然后即可回到CLOSED 可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

CLOSING :这种状态在实际情况中应该很少见,属于一种比较罕见的例外状态。正常情况下,当一方发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING 状态表示一方发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?那就是当双方几乎在同时close()一个SOCKET的话,就出现了双方同时发送FIN报文的情况,这是就会出现CLOSING 状态,表示双方都正在关闭SOCKET连接。

CLOSE_WAIT :表示正在等待关闭。怎么理解呢?当对方close()一个SOCKET后发送FIN报文给自己,你的系统毫无疑问地将会回应一个ACK报文给对方,此时TCP连接则进入到CLOSE_WAIT状态。接下来呢,你需要检查自己是否还有数据要发送给对方,如果没有的话,那你也就可以close()这个SOCKET并发送FIN报文给对方,即关闭自己到对方这个方向的连接。有数据的话则看程序的策略,继续发送或丢弃。简单地说,当你处于CLOSE_WAIT 状态下,需要完成的事情是等待你去关闭连接。

LAST_ACK :当被动关闭的一方在发送FIN报文后,等待对方的ACK报文的时候,就处于LAST_ACK 状态。当收到对方的ACK报文后,也就可以进入到CLOSED 可用状态了。

博客地址:https://ainyi.com/55

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TCP/IP 五层模型
  • HTTP状态码:
  • 三次握手
    • 通俗的说
      • 三次握手的目的
      • 四次挥手
        • 通俗的说
          • 各个状态的含义如下
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档