美文网首页
网络通信-TCP/UDP

网络通信-TCP/UDP

作者: VitaAin | 来源:发表于2019-06-15 12:09 被阅读0次

参考:
https://blog.csdn.net/zhang6223284/article/details/81414149
https://blog.csdn.net/qq_38950316/article/details/81087809
https://www.cnblogs.com/qdhxhz/p/8470997.html

TCP/IP是个协议组,可分为三个层次:网络层、传输层、应用层。
网络层有:IP协议、ICMP协议、ARP协议、RARP协议、BOOTP协议。
传输层有:TCP协议、UDP协议。
应用层有:FTP、HTTP、TELNET、SMTP、DNS等协议。

TCP,UDP,HTTP

  • TCP是基于TCP协议实现的网络文本协议,属于传输层
  • UDP是和TCP对等的,属于传输层
  • HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。基于TCP。

一、TCP

包头

TCP包头.jpg
  • 源端口、目标端口必不可少
  • 包的序号:主要用来解决乱序问题
  • 确认序号:发出去的包应该由确认,这样能知道对方是否收到,如果没收到就应该重新发送,主要解决丢包问题
  • 状态位:SYN是发起一个链接,ACK是回复,RST是重新连接,FIN是结束连接。TCP是面向连接的,因此需要双方维护连接的状态,这些状态位的包会引起双方的状态变更
  • 窗口大小:TCP要做流量控制,需要通信双方各声明一个窗口,标识自己当前的处理能力

使用TCP协议的连接建立与断开,正常过程下至少需要发送7个包才能完成,就是我们常说的三次握手,四次挥手。

TCP三次握手+四次挥手.png
  • 序列号 Sequeuece number(seq):数据包本身的序列号,初始序列号是随机的。
  • 确认号 Acknowledgment number(ack):在接收端,用来通知发送端数据成功接收。
  • 标志位,标志位只有为 1 的时候才有效:
    SYN(synchronize):同步序列编号,表示在连接建立时用来同步序号。
    ACK(Acknowledgement):确认字符,TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
    FIN(finish):用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。

建立连接:三次握手

一次TCP连接的建立需要三次握手。

TCP三次握手.jpg
  • 第一次握手
    客户端向服务端发送请求报文;即SYN=1,ACK=0,seq=x。建立连接时,客户端发送SYN包(syn=j)到服务端,并进入SYN_SENT状态,等待服务器确认;
    A:你好,我是A

  • 第二次握手
    服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYNC_RECV状态;
    B:你好,A,我是B

  • 第三次握手
    客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务端进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
    A:你好,B

为什么需要三次握手,而不是两次?

client发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达server,本来这已经是一个失效的报文,但是server端接收到这个请求报文后,还是会想client发出确认的报文,表示同意连接。假如不采用三次握手,那么只要server发出确认,新的建立就连接了,但其实这个请求是失效的请求,client是不会理睬server的确认信息,也不会向服务端发送确认的请求,但是server认为新的连接已经建立起来了,并一直等待client发来数据,这样,server的很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生,server会因为收不到确认的报文,就知道client并没有建立连接。这就是三次握手的作用。

断开连接:四次挥手

TCP四次挥手.jpg
  • 第一次挥手
    TCP发送一个FIN(结束),用来关闭客户到服务端的连接。
    客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

  • 第二次挥手
    服务端收到这个FIN,他发回一个ACK(确认),确认收到序号为收到序号+1,和SYN一样,一个FIN将占用一个序号。
    服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
    客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

  • 第三次挥手
    服务端发送一个FIN(结束)到客户端,服务端关闭客户端的连接。
    服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

  • 第四次挥手
    客户端发送ACK(确认)报文确认,并将确认的序号+1,这样关闭完成。
    客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
    服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

A:B,我不想玩了
B:哦,A你不想玩了啊,我知道了
(此时,只是A不想玩了,即不再发送数据,但B可能还有未发送完的数据,所以需要等待B也主动关闭)
B:A,好吧,我也不玩了,再见
A:好的,再见

为什么需要四次挥手?

关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢?因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。

客户端突然挂掉了怎么办?

正常连接时,客户端突然挂掉了,如果没有措施处理这种情况,那么就会出现客户端和服务器端出现长时期的空闲。解决办法是在服务器端设置保活计时器,每当服务器收到客户端的消息,就将计时器复位。超时时间通常设置为2小时。若服务器超过2小时没收到客户的信息,他就发送探测报文段。若发送了10个探测报文段,每一个相隔75秒,还没有响应就认为客户端出了故障,因而终止该连接。

累计确认

为了保证顺序性,每个包都有一个 ID。在建立连接的时候会商定起始 ID 是什么,然后按照 ID 一个个发送,为了保证不丢包,需要对发送的包都要进行应答,当然,这个应答不是一个一个来的,而是会应答某个之前的 ID,表示都收到了,这种模式成为累计应答或累计确认。

为了记录所有发送的包和接收的包,TCP 需要发送端和接收端分别来缓存这些记录,发送端的缓存里是按照包的 ID 一个个排列,根据处理的情况分成四个部分:1、发送并且确认的;2、发送尚未确认的;3、没有发送等待发送的;4、没有发送并且暂时不会发送的。这里的第三部分和第四部分就属于流量控制的内容。

对于接收端来讲,它的缓存里面的内容要简单一些:1、接收并且确认过的;2、还没接收,但是马上就能接收的;3、还没接收,但也无法接收的。

TCP为什么是可靠连接

  • 通过TCP连接传输的数据无差错,不丢失,不重复,且按顺序到达。
  • TCP报文头里面的序号能使TCP的数据按序到达。
  • 报文头里的确认序号能保证不丢包,累计确认及超时重传机制。
  • TCP拥有流量控制及拥塞控制的机制。

二、UDP

包头

UDP包头.jpg

特点

  • 不需要大量的数据结构、处理逻辑和包头字段
  • 不会建立连接,但会监听指定端口,谁都可以传给它数据,它也可以传给任何人数据,可以同时传给多个人数据
  • 不会根据网络的情况进行拥塞控制,无论是否丢包,它该怎么发还是怎么发
主要应用场景
  • 需要资源少,网络情况稳定的内网,或者对丢包不敏感的应用。比如DHCP就是基于UDP协议的
  • 不需要一对一沟通、建立连接,而是可以广播的应用。因为它不面向连接,所以可以做到一对多,承担广播或多播的协议
  • 需要处理速度快,可以容忍丢包,但是即使网络拥塞,也毫不退缩、一往无前的时候
基于UDP的几个例子
  • 直播。直播对实时性要求比较高,宁可丢包,也不要卡顿,所以很多直播应用都基于UDP实现自己的视频传输协议
  • 实时游戏。游戏的特点也是实时性比较高,在这种情况下,采用自定义的可靠的 UDP 协议,自定义重传策略,能够把产生的延迟降到最低,减少网络问题对游戏造成的影响
  • 物联网。一方面,物联网领域中断资源少,很可能知识个很小的嵌入式系统,而维护 TCP 协议的代价太大了;另一方面,物联网对实时性的要求也特别高。比如 Google 旗下的 Nest 建立 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的

TCP和UDP对比

  • TCP是面向连接的,UDP是面向无连接的
    在互通之前,面向连接的协议会先建立连接,如TCP三次握手,但UDP不会
  • UDP程序结构较简单
  • TCP是面向字节流的,UDP是基于数据报的
  • TCP保证数据正确性,UDP可能会丢包
  • TCP保证数据顺序,UDP不保证

相关文章

  • TCP UDP

    TCP和UDP的误解 一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信!TCP/...

  • 史上最简单的Sockte通信--1

    Socket,是基于网络通信协议封装的一个网络通信接口,可以支持TCP或UDP通信协议。通常是应用于TCP协议,这...

  • MFC网口编程

    Socket套接字通信 TCP UDP详解(网络通信)[https://blog.csdn.net/qq_4179...

  • Boost(二)

    boost::asio asio 主要用于网络通信,封装了socket API, 包含了TCP, ICMP,UDP...

  • 【网络通信】

    网络通信(TCP/UDP HTTP协议 TCP为什么安全) HTTP协议简介 http协议 定义了浏览器向服务器如...

  • 网络通信-TCP/UDP

    参考:https://blog.csdn.net/zhang6223284/article/details/814...

  • TCP与UDP区别

    tcp与udp都属于网络通信传输层的传输协议 TCP 举个例子:帮助理解tcp的原理流程,比如说打电话场景:A(发...

  • 初见Linux-socket

    什么叫网络编程? 就是使用网络协议,进行网络通信。数据报->UDP 流式套接字-> TCP 原始套...

  • (二)网络编程之各种协议

    TCP和UDP 1.网络通信协议 网络通信协议:为什么要有网络通信协议呢?就好比在现实中要有法律法规一样,这样才能...

  • 网络编程

    今日介绍内容 1、网络通信协议 2、UDP通信 3、TCP通信 第一章 网络通信协议 通过计算机网络可以使...

网友评论

      本文标题:网络通信-TCP/UDP

      本文链接:https://www.haomeiwen.com/subject/hislfctx.html