Linux-TCP/UDP

OSI七层模型
    OSI(Open System Interconnection,开放系统互联)七层网络模型成为开放式系统互联参考模型,是一个把网络通信在逻辑上的定义,也可以理解成为定义了通用的网络通信规范。而我们的数据在网络中传输的过程,实际上就是如下图的封装和解封装的过程,发送方通过各种封装处理,把数据转换成比特流的形式,比特流在信号传输的硬件媒介中传输,接收方再把比特流进行解封装处理。

Linux-TCP/UDP_第1张图片

TCP/IP协议族
    把7层网络模型合并成4层

Linux-TCP/UDP_第2张图片

各层协议举例如下

Linux-TCP/UDP_第3张图片

UDP协议

  UDP(User Datagram Protocol)即用户数据报协议,其传输机制决定了它的最大优点快,同时也决定了它最大的缺点不可靠、不稳定。
  UDP是无连接的,发送数据之前不需要建立连接(TCP需要)。减少了开销和延时。
  UDP是面向报文的,对IP数据报只做简单封装(8字节UDP报头)。减少报头开销。
  UDP没有阻塞机制,宁愿阻塞时丢弃数据不传,也不阻塞造成延时。
  UDP支持一对一、一对多、多对一、多对多通信。

TCP协议
  TCP(Transmission Control Protocol)传输控制协议,相对于UDP,TCP是面向连接的、提供可靠的数据传输服务。同时也是较UDP开销较大的、传输速度较慢的。
  TCP 提供可靠的、面向连接的数据传输服务。使用TCP通信之前,需要进行“三次握手”建立连接,通信结束后还要使用“四次挥手”断开连接。
  TCP 是点对点的连接。一条TCP连接只能连接两个端点。
  TCP 提供可靠传输,无差错、不丢失、不重复、按顺序。
  TCP 提供全双工通信,允许通信双方任何时候都能发送数据,发送方设有发送缓存,接收方设有接收缓存。
  TCP 面向字节流 。TCP 并不知道所传输的数据的含义,仅把数据看作一连串的字节序列,它也不保证接收方收到的数据块和发送方发出的数据块具有大小对应关系。

TCP建立连接的三次握手

Linux-TCP/UDP_第4张图片

  (1)Client首先向Server发送连接请求报文段,同步自己的seq(x),Client进入SYN_SENT状态。
  (2)Server收到Client的连接请求报文段,返回给Client自己的seq(y)以及ack(x+1),Server进入SYN_REVD状态。
  (3)Client收到Server的返回确认,再次向服务器发送确认报文段ack(y+1),这个报文段已经可以携带数据了。Client进入ESTABLISHED状态。
  (4)Server再次收到Client的确认信息后,进入ESTABLISHED状态。
  TCP连接至此建立起来了。为什么要做三次握手呢?握手的过程实际上是在通知对方自己的初始化序号(Initial Sequence Number),简称ISN,也就是上图中的x和y。x和y会被当作之后传输数据的一个依据,以保证TCP报文在传输过程中不会混乱。

  我们回到TCP Header结构来看,Sequence Number和Acknowledgment Number都是占32位,所以seq和ack的取值范围是0 ~ 2^32-1。seq和ack每增加到2^32-1,则重新从0开始。值得一提的是,seq的初始值(ISN)并不是每次都从0开始的。我们设想一下,如果是从0开始,那么当TCP三次握手建立连接完成后,Client发送了30个报文,然后Client断线了。于是Client重连,再次用0作为初始的seq,这样就会出现两个报文具有相同的seq,就出现了混乱。事实上TCP的做法是每隔4微秒就对ISN做一次加1操作,当ISN到达2^32-1后再次从0开始的时候,已经过去了几个小时,之前的seq=0的报文已经不存在于这次连接中了,这样就避免了上面的问题。

TCP断开连接的四次挥手

Linux-TCP/UDP_第5张图片

  (1)Client向Server发送断开连接请求的报文段,seq=m(m为Client最后一次向Server发送报文段的最后一个字节序号加1),Client进入FIN-WAIT-1状态。
  (2)Server收到断开报文段后,向Client发送确认报文段,seq=n(n为Server最后一次向Client发送报文段的最后一个字节序号加1),ack=m+1,Server进入CLOSE-WAIT状态。此时这个TCP连接处于半开半闭状态,Server发送数据的话,Client仍然可以接收到。
  (3)Server向Client发送断开确认报文段,seq=u(u为半开半闭状态下Server最后一次向Client发送报文段的最后一个字节序号加1),ack=m+1,Server进入LAST-ACK状态。
  (4)Client收到Server的断开确认报文段后,向Server发送确认断开报文,seq=m+1,ack=u+1,Client进入TIME-WAIT状态。
  (5)Server收到Client的确认断开报文,进入CLOSED状态,断开了TCP连接。
  (6)Client在TIME-WAIT状态等待一段时间(时间为2*MSL((Maximum Segment Life)),确认Client向Server发送的最后一次断开确认到达(如果没有到达,Server会重发步骤(3)中的断开确认报文段给Client,告诉Client你的最后一次确认断开没有收到)。如果Client在TIME-WAIT过程中没有再次收到Server的报文段,就进入CLOSES状态。TCP连接至此断开。

TCP连接可靠性的体现
  (1)TCP报文段的长度可变,根据收发双方的缓存状态、网络状态而调整。
  (2)当TCP收到发自TCP连接另一端的数据,它将发送一个确认。
  (3)当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段,如果不能及时收到一个确认,将重发这个报文段。
  (4)TCP将保持它首部和数据的检验和。如果通过检验和发现报文段有差错,这个报文段将被丢弃,等待超时重传。
  (5)TCP将数据按字节排序,报文段中有序号,以确保顺序的正确性。
  (6)TCP还能提供流量控制。TCP连接的每一方都有收发缓存。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。

  需要注意的是,TCP报文传输采用接受后返回确认的方式来保证报文传输的可靠性,并不是意味着发送方在发送一个报文段后就进入等待确认状态,让后面的报文段等着。也不是接收方在接收到一个报文后,对每一个报文都进行回复确认。

  真实的情况是,对于发送方,在发送一个报文段后,复制一份该报文段的副本,然后继续进行下一个报文段的发送,如果没有得到发送方的回复确认,就对该报文段进行超时重发。对于接收方来说,则采用“积累确认”的方式进行回复。接收者收到多个连续的报文段后,只回复确认最后一个报文段,表示在这之前的数据都已收到。以此达到提升传输效率的目的。

TCP与UDP区别  
    (1)基于连接与无连接  
    (2)TCP要求系统资源较多,UDP较少  
    (3)UDP程序结构较简单   
    (4)流模式(TCP)与数据报模式(UDP),TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的  
    (5)TCP保证数据正确性,UDP可能丢包;TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
    (6)TCP保证数据顺序,UDP不保证   
    (7)UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
    (8)每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
    (9)TCP首部开销20字节;UDP的首部开销小,只有8个字节
    (10)TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道 

UDP应用场景 
    (1)面向数据报方式  
    (2)网络数据大多为短消息   
    (3)拥有大量Client  
    (4)对数据安全性无特殊要求  
    (5)网络负担非常重,但对响应速度要求高

你可能感兴趣的:(Linux)