【计算机网络 - 基础问题】每日 3 题(二十四)

ops/2024/9/25 14:35:21/

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
📝推荐参考地址:https://www.xiaolincoding.com/(这个大佬的专栏非常有用!)

70. 解释 TCP 为什么是流协议?怎么分割?

当用户消息通过 TCP 协议传输时,消息可能会被操作系统分组成多个的 TCP 报文,也就是一个完整的用户消息被拆分成多个 TCP 报文进行传输。

这时,接收方的程序如果不知道发送方发送的消息的长度,也就是不知道消息的边界时,是无法读出一个有效的用户消息的,因为用户消息被拆分成多个 TCP 报文后,并不能像 UDP 那样,一个 UDP 报文就能代表一个完整的用户消息。

举个实际的例子来说明。

发送方准备发送「Hi.」和「I am Xiaolin」这两个消息。

在发送端,当我们调用 send 函数完成数据“发送”以后,数据并没有被真正从网络上发送出去,只是从应用程序拷贝到了操作系统内核协议栈中。

至于什么时候真正被发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。也就是说,我们不能认为每次 send 调用发送的数据,都会作为一个整体完整地消息被发送出去。

如果我们考虑实际网络传输过程中的各种影响,假设发送端陆续调用 send 函数先后发送「Hi.」和「I am Xiaolin」报文,那么实际的发送很有可能是这几种情况。

第一种情况,这两个消息被分到同一个 TCP 报文,像这样:

在这里插入图片描述

第二种情况,「I am Xiaolin」的部分随「Hi」在一个 TCP 报文中发送出去,像这样:

在这里插入图片描述

第三种情况,「Hi.」的一部分随 TCP 报文被发送出去,另一部分和「I am Xiaolin」一起随另一个 TCP 报文发送出去,像这样。

在这里插入图片描述

类似的情况还能举例很多种,这里主要是想说明,我们不知道「Hi.」和「I am Xiaolin」这两个用户消息是如何进行 TCP 分组传输的。

因此,我们不能认为一个用户消息对应一个 TCP 报文,正因为这样,所以 TCP 是面向字节流的协议。

当两个消息的某个部分内容被分到同一个 TCP 报文时,就是我们常说的 TCP 粘包问题,这时接收方不知道消息的边界的话,是无法读出有效的消息。

要解决这个问题,要交给应用程序。

71. TCP 粘包问题

  1. 固定长度

指定固定的长度,实现起来简单方便,但是可能会浪费内存资源。

  1. 特殊分隔符

我们可以在两个用户消息之间插入一个特殊的字符串,这样接收方在接收数据时,读到了这个特殊字符,就把认为已经读完一个完整的消息。

HTTP 是一个非常好的例子,通过 \r\n 来进行分隔。

在这里插入图片描述

HTTP 通过设置回车符、换行符作为 HTTP 报文协议的边界。

有一点要注意,这个作为边界点的特殊字符,如果刚好消息内容里有这个特殊字符,我们要对这个字符转义,避免被接收方当作消息的边界点而解析到无效的数据。

  1. 自定义消息结构

我们可以自定义一个消息结构,由包头和数据组成,其中包头包是固定大小的,而且包头里有一个字段来说明紧随其后的数据有多大。

比如这个消息结构体,首先 4 个字节大小的变量来表示数据长度,真正的数据则在后面。

struct { u_int32_t message_length; char message_data[]; 
} message;

当接收方接收到包头的大小(比如 4 个字节)后,就解析包头的内容,于是就可以知道数据的长度,然后接下来就继续读取数据,直到读满数据的长度,就可以组装成一个完整到用户消息来处理了。

72. protobuf 了解吗?

Protobuf 是用于数据序列化和反序列化的格式,类似于 JSON。但它们有以下几点区别:

  • 数据大小:Protobuf 是一种二进制格式,相对于 JSON 来说,数据大小更小,序列化和反序列化的效率更高,因此在网络传输和存储方面具有一定的优势。
  • 性能:由于 Protobuf 是二进制格式,相对于 JSON 来说,解析速度更快,占用的 CPU 和内存资源更少,因此在高并发场景下,性能更优。
  • 可读性:JSON 是一种文本格式,可读性更好,易于调试和排查问题。而 Protobuf 是一种二进制格式,可读性较差。

Protobuf 适用于高性能、大数据量、高并发等场景,而 JSON 适用于数据交换、易读性要求高的场景。


http://www.ppmy.cn/ops/115818.html

相关文章

花园管理系统

基于springbootvue实现的花园管理系统 (源码L文ppt)4-074 4功能结构 为了更好的去理清本系统整体思路,对该系统以结构图的形式表达出来,设计实现该“花开富贵”花园管理系统的功能结构图如下所示: 图4-1 系统总体结…

Ubuntu24.04下编译OpenCV + OpenCV Contrib 4.10.0

1. 安装必要软件 sudo apt update sudo apt-get install -y build-essential sudo apt-get install -y cmake-gui git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install -y python3-dev python3-numpy libtbbmalloc2 libtbb-…

Lumen5——AI视频制作,提取关键信息生成带有视觉效果的视频

一、Lumen5介绍 Lumen5 是一款基于人工智能的自动化视频制作平台,专为非专业用户设计,帮助其将博客、文章、新闻等文字内容快速转换为视频。Lumen5 的目标是简化视频制作流程,让内容创作者、市场营销人员、社交媒体团队等无需视频制作经验即…

初识MySQL

1.初识MySQL 1.什么是数据库 数据库(Database,简称DB) 概念: 长期存放在计算机内,有组织、可共享的大量数据的集合,是一个数据“仓库” 作用: 保存、管理数据 数据库总览 关系型数据库(…

怎么在Proteus中找到排阻

1、打开安装好的Proteus,点击上方菜单栏中的“库”,再选择“从库选取零件”,或者在左侧元件列表中单击鼠标右键,再点击右键菜单中的“从库中挑选”选项。 2、之后会打开元器件库,我们打开类别中的“Resistors”&#x…

详解 CMake 命令:启用详细 Makefile 输出

详解 CMake 命令:启用详细 Makefile 输出 这条 CMake 命令包含了一些重要的组成部分和参数,下面我将逐一进行解释: 命令概览 命令内容为: cmake ../Lesson1_1 -DCMAKE_VERBOSE_MAKEFILEON各部分解释 cmake: 这是调用 CMake 命…

CNVD漏洞和证书挖掘经验总结

前言 本篇文章主要是分享一下本人挖掘CVND漏洞碰到的一些问题,根据过往成功归档的漏洞和未归档的漏洞总结出的经验,也确实给审核的大佬们添了很多麻烦(主要真的没人教一下,闷着头尝试犯了好很多错误,希望各位以后交一个…

python如何实现数据看板报表的几种方法

在Python中实现数据看板报表,可以通过多种方式,包括但不限于使用专门的库如Matplotlib、Seaborn、Plotly、Dash(用于Web应用)、Pandas的内置绘图功能,以及Panel(一个用于构建分析应用的Python库&#xff09…