TCP/IP传输层

传输层一直都没有好好总结一下,最近又学了一遍,但也的确是时间有点紧张,来不及写总结,以后我再把这方面的知识点给补上。

对于传输层主要有几个方面要掌握:

1、TCP,UDP的概念,区别等;

2、TCP的链接建立和释放的过程,每次发送的字段都是什么含义;

3、TCP的状态机;

一、TCP、UDP的区别

以前在学课本的时候肯定都学到过这样的概念,TCP是面向连接的,提供面向字节流的可靠的传输;UDP是无连接的,提供面向报文的不可靠的传输。但为什么说TCP是面向字节流,UDP是面向报文?为什么TCP提供传输可靠,UD不可靠?

1、TCP面向字节流,UDP面向报文

UDP将应用层交下来的的数据不合并,不拆分,对其加上源、目的端口等头信息就下发给网络层。无论应用层下发的数据多长,UDP都会统统发送,一次发送一个。报文的大小需要应用层控制,如果超过最大传输单元,那么IP层可能会对其分片传输;

TCP是面向字节流的,它会把应用层交下来的数据当做无结构的字节流,TCP会根据网络拥赛等情况来确定每次发送的报文的大小。

2、TCP是可靠的,UDP是不可靠的。

TCP是可靠的,TCP通过三次握手建立连接,连接建立过程中要发送序列号,确认号,窗口大小等信息。这就是实现可靠传输的基础。为啥这么说:

1)数据排序

TCP有专门的序列号Sequence Number,在接收端根据序列号对数据进行重组。

2)重传机制

TCP提供了错误重传、超时重传等机制。

3)流量控制

TCP提供了一个流量窗口,用来实现对流量的控制。

4) 拥塞控制

TCP提供了慢启动、拥塞避免、快速重传、快速恢复等机制。

相反,UDP的机制是完全不同的。UDP只管发出去,它不会对数据是否正确发送,正确接收进行检查。

3、优缺点

说了上面TCP和UDP的机制,优缺点就可明显了。主要说缺点:

TCP因为建立连接需要三次握手,因此要发送很多包,浪费带宽,速率相比UDP慢。而且需要client和server都需要在线才能正常通信。然而UDP不需握手机制,传输较快。而且, 不需要双方都在线,server不需要维护大量连接,节省资源。

UDP是不可靠的。

关于TCP建立过程以及状态机,就看下面的文章,我最近看了这篇文章,总结的很好: TCP介绍

今天学习了一下TCP粘包和拆包。粘包和拆包是两种TCP中两种刹常见的现象。因为本身TCP传输是面向字节流的,而其传输有着最大报文长度限制,且发送端和接收端都有报文缓冲区。那为什么会有缓冲区呢。这是因为TCP为了避免造成资源的浪费,小的数据要分组发送,采用的算法叫Nagle算法。其逻辑大致如下:

if there is new data to send
  if the window size >= MSS and available data is >= MSS
    send complete MSS segment now
  else
    if there is unconfirmed data still in the pipe
      enqueue data in the buffer until an acknowledge is received
    else
      send data immediately
    end if
  end if
end if

当发送端连续多次发送数据,且数据长度不够,可能就会在TCP发送缓冲区发生粘包,一起发送给接收方。TCP并不知道应用层的数据的实际大小,更加不会区分。这种现象就是粘包;

当发送端一次发送数据的长度超过了TCP的单次最大报文长度,TCP就会将其拆分,分多次发送。这种现象就是拆包。

无论是发生粘包还是拆包,接收端接收到的原始应用数据都是乱的。所以,应用层必须有着某种策略去解决TCP传输层导致的粘包与拆包的问题。

对于这种问题,其实已经有很多成熟的解决方案。比如:

  1. 每次发送的消息数据都是固定长度,如果不足的,就用某些字符左(或者右)补齐。
  2. 消息之间使用特殊字符分割,比如换行符等等。
  3. 消息使用消息头或者消息体构成。

目前比较典型的就是Netty和Dubbo中的解决方案。

在Netty中,它是实现了多个解码器。

  • LineBasedFrameDecoder 使用回车换行符
  • DelimiterBasedFrameDecoder(添加特殊分隔符报文来分包)
  • FixedLengthFrameDecoder(使用定长的报文来分包)
  • LengthFieldBasedFrameDecoder

关于每个Decoder怎么实现的,可以看下面的参考资料或者Netty源码。

Dubbo虽然使用的是Netty,但是其并没有使用Netty内置的几种解码器。它实现了自己的编码和解码器。在客户端,它会对消息进行编码,一个完整消息具备消息头和消息体。具体可以看下面的参考资料。

参考资料:

TCP粘包/拆包与Netty解决方案

【Dubbo】编码解码

TCP-IP详解:Nagle算法

--------EOF---------
微信分享/微信扫码阅读