正文
在阅读UDP和TCP协议时,会看到数据报、字节流字样,那么什么是数据报、字节流、字符流呢?
报文(message)
我们将位于应用层的信息分组称为报文。报文是网络中交换与传输的数据单元,也是网络传输的单元。 报文包含了将要发送的完整的数据信息,其长短不需一致。报文在传输过程中会不断地封装成分组、包、帧来传输, 封装的方式就是添加一些控制信息组成的首部,那些就是报文头。
报文段(segment)
通常是指起始点和目的地都是传输层的信息单元。
数据报(datagram)
面向无连接的数据传输,其工作过程类似于报文交换。采用数据报方式传输时,被传输的分组称为数据报。 通常是指起始点和目的地都使用无连接网络服务的网络层的信息单元。(指IP数据报)
数据报是通过网络传输的数据的基本单元,包含一个报头(header)和数据本身,其中报头描述了数据的目的地以及和其它数据之间的关系。 数据报是完备的、独立的数据实体,该实体携带要从源计算机传递到目的计算机的信息, 该信息不依赖以前在源计算机和目的计算机以及传输网络间交换。
分组/包(packet)
分组是在网络中传输的二进制格式的单元,为了提供通信性能和可靠性,每个用户发送的数据会被分成多个更小的部分。 在每个部分的前面加上一些必要的控制信息组成的首部,有时也会加上尾部,就构成了一个分组。它的起始和目的地是网络层。
帧(frame)
帧是数据链路层的传输单元。它将上层传入的数据添加一个头部和尾部,组成了帧。它的起始点和目的点都是数据链路层。
数据单元(data unit)
指许多信息单元。常用的数据单元有服务数据单元(SDU)、协议数据单元(PDU)。
SDU是在同一机器上的两层之间传送信息。PDU是发送机器上每层的信息发送到接收机器上的相应层(同等层间交流用的)。
总结
应用层——消息
传输层——报文段(segment)/数据报(datagram) (注:TCP叫TCP报文段,UDP叫UDP数据报,也有人叫UDP段)
网络层——分组、数据包(packet)
链路层——帧(frame)
物理层——P-PDU(bit)
其实,segment,datagram,packet,frame是存在于同条记录中的,是基于所在协议层不同而取了不同的名字。 我们可以用一个形象的例子对数据包的概念加以说明:我们在邮局邮寄产品时,虽然产品本身带有自己的包装盒, 但是在邮寄的时候只用产品原包装盒来包装显然是不行的。必须把内装产品的包装盒放到一个邮局指定的专用纸箱里, 这样才能够邮寄。这里,产品包装盒相当于数据包,里面放着的产品相当于可用的数据, 而专用纸箱就相当于帧,且一个帧中通常只有一个数据包。
注:Datagram: This is used in 2 layers. If the network protocol is IP, the unit of data is called Datagram. At transport layer, if protocol is UDP, we use datagram there as well. Hence, we differentiate them as UDP Datagram, IP Datagram. 翻译过来是, 数据报:分两层使用。如果网络协议是IP,则数据单元称为数据报datagram。 在传输层,如果协议是UDP,我们也使用数据报datagram。因此,我们将它们区分为 UDP数据报 和 IP数据报。
字节流与字符流
字节流是由字节组成的,字符流是由字符组成的。
什么是字节流?传输过程中,传输数据的最基本单位是字节的流,一个不包含边界数据的连续流;字节流是由字节组成的,主要用在处理二进制数据。
什么是字符流?字符流,传输过程中,传输数据的最基本单位是字符的流。
字节流 与 字符流 的区别:
- 字符编码方式不同,有时候一个字符使用的字节数也不一样,比如ASCLL方式编码的字符,占一个字节; 而UTF-8方式编码的字符,一个英文字符需要一个字节,一个中文需要三个字节。
- 字节数据是二进制形式的,要转成我们能识别的正常字符,需要选择正确的编码方式。 我们生活中遇到的乱码问题就是字节数据没有选择正确的编码方式来显示成字符。
- 从本质上来讲,写数据(即输出)的时候,字节也好,字符也好,本质上都是没有标识符的,需要去指定编码方式。
- 但读数据的时候,如果我们需要去“看数据”,那么字节流的数据需要指定字符编码方式,这样我们才能看到我们能识别的字符; 而字符流,因为已经选择好了字符编码方式,通常不需要再改了(除非定义的字符编码方式与数据原有的编码方式不一致!)
- 在传输方面上,由于计算机的传输本质都是字节,而一个字符由多个字节组成,转成字节之前先要去查表转成字节, 所以传输时有时候会使用缓冲区。
流
流就是stream,一个连续的字节队列。
流是程序输入或输出的一个连续的字节序列,设备(例如鼠标,键盘,磁盘,屏幕和打印机)的输入和输出都是用流来处理的。 在C语言中,所有的流均以文件的形式出现,不一定是物理磁盘文件,还可以是对应与某个输入/输出源的逻辑文件
流式传输主要指将整个音频和视频及三维媒体等多媒体文件经过特定的压缩方式解析成一个个压缩包, 由视频服务器向用户计算机顺序或实时传送。
TCP字节流与UDP数据报的区别
1、TCP
TCP是一种流模式的协议,UDP是一种数据报模式的协议。“流模式”与“数据包模式”在编程的时候有什么区别呢?
打个比方比喻TCP,你家里有个蓄水池,你可以里面倒水,蓄水池上有个龙头,你可以通过龙头将水池里的水放出来, 然后用各种各样的容器装(杯子、矿泉水瓶、锅碗瓢盆)接水。
上面的例子中,往水池里倒几次水和接几次水是没有必然联系的,也就是说你可以只倒一次水,然后分10次接完。 另外,水池里的水接多少就会少多少;往里面倒多少水,就会增加多少水,但是不能超过水池的容量,多出的水会溢出。
结合TCP的概念,水池就好比接收缓存,倒水就相当于发送数据,接水就相当于读取数据。 好比你通过TCP连接给另一端发送数据,你只调用了一次 write,发送了100个字节,但是对方可以分10次收完,每次10个字节; 你也可以调用10次write,每次10个字节,但是对方可以一次就收完。 但是,(假设数据都能到达)你发送的数据量不能大于对方的接收缓存(流量控制), 如果你硬是要发送过量数据,则对方的缓存满了就会把多出的数据丢弃。
2、UDP
UDP和TCP不同,发送端调用了几次write,接收端必须用相同次数的read读完。 UPD是基于报文的,在接收的时候,每次最多只能读取一个 报文,报文和报文是不会合并的,如果缓冲区小于报文长度, 则多出的部分会被丢弃。也就说,如果不指定MSG_PEEK标志,每次读取操作将消耗一个报文。
3、为什么
其实,这种不同是由TCP和UDP的特性决定的。TCP是面向连接的,也就是说,在连接持续的过程中, socket中收到的数据都是由同一台主机发出的(劫持什么的不考虑),因此,只要保证数据是有序的到达就行了, 至于每次读取多少数据自己看着办。
而UDP是无连接的协议,也就是说,只要知道接收端的IP和端口,且网络是可达的,任何主机都可以向接收端发送数据。 这时候,如果一次能读取超过一个报文的数据,则会乱套。比如,主机A发送了报文P1,主机B发送了报文P2, 如果能够读取超过一个报文的数据,那么就会将P1和P2的数据合并在了一 起,这样的数据是没有意义的。
两个协议其他区别
TCP(Transmission Control Protocol)传输控制协议:
该协议主要用于在主机间建立一个虚拟连接,以实现高可靠性的数据包交换。IP协议可以进行IP数据包的分割和组装, 但是通过IP协议并不能清楚地了解到数据包是否顺利地发送给目标计算机。而使用TCP协议就不同了, 在该协议传输模式中在将数据包成功发送给目标计算机后,TCP会要求发送一个确认;如果在某个时限内没有收到确认, 那么TCP将重新发送数据包。另外,在传输的过程中,如果接收到无序、丢失以及被破坏的数据包,TCP还负责恢复。
传输控制协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,通常由IETF的RFC793说明。 在简化的计算机网络OSI模型中,它完成运输层所指定的功能。
UDP (User Datagram Protocol) 用户数据报协议:
用户数据报协议(UDP)是 ISO参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。 UDP 协议基本上是 IP 协议与上层协议的接口。UDP协议使用端口分辨运行在同一台设备上的多个应用程序。
由于大多数网络应用程序都在同一台机器上运行,计算机上必须能够确保目的地机器上的软件程序能从源地址机器处获得数据包, 以及源计算机能收到正确的回复。这是通过使用UDP 的“端口号”完成的。
区别:
1、基于连接与无连接
TCP—传输控制协议提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接, 之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
每个数据包的传输过程是:先建立链路、数据传输、然后清除链路。 受端和发端不但顺序一致,而且内容相同。它的可靠性高。
UDP—用户数据报协议是一种无连接的传输层协议。各自在网络中独立传输,传输中不管其顺序。 数据到达接收端后,应用再写逻辑进行排序组装,遇有包丢失、差错和失序等情况,通过请求重发来解决。 UDP是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去, 但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度快。
TCP 报文结构中有:源端口号,目的端口号,序号、确认号等。
UDP 报文结构中有:源端口号,目的端口号等。
源IP地址、目标IP地址,都在网络层再添加到IP首部中。
2、对系统资源的要求(TCP较多,UDP少)
3、UDP程序结构较简单
4、流模式与数据报模式
5、TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
6、TCP是面向连接、可靠的字节流服务 ,UDP 并不提供对 IP协议的可靠机制、流量控制以及错误恢复功能等。
IP报文
版本(version):占4位,指IP协议的版本。通信双方使用的IP协议的版本必须一致。 目前广泛使用的IP协议版本号为4(即IPv4)。版本号为6,即IPv6。
首部长度(网际报文头长度IHL):占4位,可表示的最大十进制数值是15。
首部长度字段所表示的单位是32位(4字节,与TCP首部中长度字段单位一致)。因为IP首部的固定长度是20字节, 因此首部长度字段的最小值为5(0101)。当首部长度为15(1111)时,表示的长度为60字节当IP分组的首部长度不是4的整数倍时, 必须利用最后的填充字段加以填充达到4的整数倍。
区分服务(tos):占1字节,用来获得更好的服务。这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过。 只有在区分服务时,这个字段才起作用。在一般情况下都不使用这个字段。
总长度(totlen):占2字节,指首部和数据之和的长度,单位为字节。能表示的最大长度为65535字节。 在IP层下面的链路层协议规定了一个数据帧的数据字段的最大长度,这称为最大传输单元MTU(maximum transfer unit)。 当一个IP数据报封装成链路层的帧时,此数据报的总长度(即首部加上数据部分)一定不能超过下面的链路层所规定的的MTU值。
以太网规定MTU为1500字节。若所传送的数据报长度超过链路层的MTU值,就必须把过长的数据进行分片处理。
标识(identification):占2字节。网络层软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。 但这个“标识”并不同于TCP首部中的序号,因为IP是无连接的服务,数据报不存在按序接收的问题。 当数据报长度超过网络的MTU而必须分片时,这个标识字段的值就被复制到所有被分片报文片的标识字段中。 相同的标识字段的值使分片后的各数据报片最后能正确地重装层原来的数据。
标志(flag):占3位,目前只有两位有意义。
标志字段中间的一位记为DF(dongt fragment),意思是“不能分片”。当DF=0时才允许分片。标志字段最低位MF(more fragment)。 MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个。
片偏移(offsetfrag):占13位。片偏移指出:较长的IP报文在分片后,某片在原分组中的相对位置。 也就是说,相对于用户数据字段的起点,该片从何处开始。片偏移以8个字节为偏移单位。没片的长度一定是8字节的整数倍。
生存时间(TTL):占8位,英文缩写TTL(Time To Live),表明数据报在网络中的寿命。由发出数据报的源点设置这个字段。 目的是防止无法交付的数据无限制地在互联网中兜圈子。路由器在每次转发数据报之前就把TTL值减1。 若TTL值减小到零,就丢弃此报文,不在转发。
协议:占8位,协议字段指出此数据报携带的数据是使用何种协议(上面数据包中协议字段为6表示使用TCP协议), 以便使用的目的主机的IP层知道应将数据部分上交给哪个协议进行处理。
常见的协议号:
协议名 ICMP IGMP IP TCP IPv6 UDP
协议字段值 1 2 4 6 41 17
首部检验和(checksum):占16位,也常成为校验和。这个字段只检验数据报的首部,但不包括数据部分(与UDP、TCP中的检验和不同)。 IP数据报每经过一个路由器,路由器都需要重新计算一下首部检验和(IP首部中的TTL、标志、片偏移等都可能发生变化)
数据分片
例如:一数据报的总长度为3820字节,数据部分为3800字节(IP首部为固定20字节),需要分片传输。 假设每片IP报文长度不超过1420字节。去掉固定首部长度20字节,每片报文数据部分长度不超过1400。 于是分成3个数据报片,其数据部分长度分别为1400、1400、1000字节。 原始数据报首部被复制为各数据报片的首部,只需要改变有关字段的值。
报文首部中与分片有关的字段中数值,标识部分是任意给定的值:
以太帧
以太帧起始部分由前同步码和帧开始定界符组成,后面紧跟着一个以太网报头,以 MAC 地址说明目的地址和源地址。 以太帧的中部是该帧负载的包含其他协议报头的数据包,如 IP 协议。
以太帧由一个 32 位冗余校验码结尾,用于检验数据传输是否出现损坏。以太帧结构如图所示。
上图中每个字段的含义如下表所示:
前同步码:用来使接收端的适配器在接收 MAC 帧时能够迅速调整时钟频率,使它和发送端的频率相同。 前同步码为 7 个字节,1 和 0 交替。
帧开始定界符:帧的起始符,为 1 个字节。前 6 位 1 和 0 交替,最后的两个连续的 1 表示告诉接收端适配器: “帧信息要来了,准备接收”。
目的MAC地址:接收帧的网络适配器的物理地址(MAC 地址),为 6 个字节(48 比特)。作用是当网卡接收到一个数据帧时, 首先会检查该帧的目的地址,是否与当前适配器的物理地址相同,如果相同,就会进一步处理;如果不同,则直接丢弃。
源MAC地址:发送帧的网络适配器的物理地址(MAC 地址),为 6 个字节(48 比特)。
类型:上层协议的类型。由于上层协议众多,所以在处理数据的时候必须设置该字段,标识数据交付哪个协议处理。 例如,字段为 0x0800 时,表示将数据交付给 IP 协议。
数据:也称为有效载荷,表示交付给上层的数据。以太网帧数据长度最小为 46 字节,最大为 1500 字节。 如果不足 46 字节时,会填充到最小长度。最大值也叫最大传输单元(MTU)。
帧检验序列 FCS 检测该帧是否出现差错,占 4 个字节(32 比特)。发送方计算帧的循环冗余码校验(CRC)值,把这个值写到帧里。 接收方计算机重新计算 CRC,与 FCS 字段的值进行比较。如果两个值不相同,则表示传输过程中发生了数据丢失或改变。 这时,就需要重新传输这一帧。
ICMP报文
ICMP(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议, 用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。 这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
ICMP消息名助记符:
消息类型 消息代码 消息含义 消息助记符
type:0 code:0 :表示回显应答(ping应答) Echo
type:8 code:0 :表示回显请求(ping请求) Echo-reply
type:3 code:0 :网络不可达 Net-unreachable
type:3 code:1 :主机不可达 Host-unreachable
type:3 code:2 :协议不可达 Protocol-unreachable
type:5 code:0 :网络重定向 Net-redirect
type:5 code:1 :主机重定向 Host-redirect
type:5 code:2 :服务类型和网络重定向 Net-tos-redirect
type:5 code:3 :服务类型和主机重定向 Host-tos-redirect
type:11 code:0 :超时
type:12 code:0 :参数存在问题 Parameter-problem
type:13 code:0 :时间戳请求 Timestamp-request
type:14 code:0 :时间戳响应 Timestamp-reply
type:15 code:0 :信息请求 Information-request
type:16 code:0 :信息应答 Information-reply
参考资料
报文、报文段、分组、包、数据报、帧、数据流的概念区别 https://blog.csdn.net/a3192048/article/details/84671340
浅析TCP字节流与UDP数据报的区别 https://www.linuxidc.com/Linux/2014-11/109545.htm
TCP IP ICMP 以太网帧格式 https://blog.csdn.net/u013416923/article/details/125812525
数据报 https://baike.baidu.com/item/数据报/2194617
什么是字节流? https://www.php.cn/faq/416556.html
UDP报文观测 https://blog.csdn.net/dai_xaetford/article/details/110452512