OpenCV 如何使用 XML 和 YAML 文件的文件输入和输出

 返回:OpenCV系列文章目录(持续更新中......)

上一篇:如何利用OpenCV4.9离散傅里叶变换

下一篇:

目标

本文内容主要介绍:

  • 如何使用 YAML 或 XML 文件打印和读取文件和 OpenCV 的文本条目?
  • 如何对 OpenCV 数据结构做同样的事情?
  • 如何为您的数据结构执行此操作?
  • 使用 OpenCV 数据结构,例如 cv::FileStorage , cv::FileNode or cv::FileNodeIterator .

源代码
 

需要源码的朋友可以前往官网下载:

下面是一个示例代码,说明如何实现目标列表中列举的所有内容。

#include <opencv2/core.hpp>
#include <iostream>
#include <string> 
using namespace cv;
using namespace std; 
static void help(char** av)
{cout << endl<< av[0] << " shows the usage of the OpenCV serialization functionality." << endl<< "usage: " << endl<< av[0] << " outputfile.yml.gz" << endl<< "The output file may be either XML (xml) or YAML (yml/yaml). You can even compress it by "<< "specifying this in its extension like xml.gz yaml.gz etc... " << endl<< "With FileStorage you can serialize objects in OpenCV by using the << and >> operators" << endl<< "For example: - create a class and have it serialized" << endl<< " - use it to read and write matrices." << endl;
} 
class MyData
{
public:MyData() : A(0), X(0), id(){}explicit MyData(int) : A(97), X(CV_PI), id("mydata1234") // explicit to avoid implicit conversion{}void write(FileStorage& fs) const //Write serialization for this class{fs << "{" << "A" << A << "X" << X << "id" << id << "}";}void read(const FileNode& node) //Read serialization for this class{A = (int)node["A"];X = (double)node["X"];id = (string)node["id"];}
public: // Data Membersint A;double X;string id;
}; 
//These write and read functions must be defined for the serialization in FileStorage to work
static void write(FileStorage& fs, const std::string&, const MyData& x)
{x.write(fs);
}
static void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){if(node.empty())x = default_value;elsex.read(node);
} 
// This function will print our custom class to the console
static ostream& operator<<(ostream& out, const MyData& m)
{out << "{ id = " << m.id << ", ";out << "X = " << m.X << ", ";out << "A = " << m.A << "}";return out;
} 
int main(int ac, char** av)
{if (ac != 2){help(av);return 1;} string filename = av[1];{ //writeMat R = Mat_<uchar>::eye(3, 3),T = Mat_<double>::zeros(3, 1);MyData m(1); FileStorage fs(filename, FileStorage::WRITE);// or:// FileStorage fs;// fs.open(filename, FileStorage::WRITE); fs << "iterationNr" << 100;fs << "strings" << "["; // text - string sequencefs << "image1.jpg" << "Awesomeness" << "../data/baboon.jpg";fs << "]"; // close sequence fs << "Mapping"; // text - mappingfs << "{" << "One" << 1;fs << "Two" << 2 << "}"; fs << "R" << R; // cv::Matfs << "T" << T; fs << "MyData" << m; // your own data structures fs.release(); // explicit closecout << "Write Done." << endl;} {//readcout << endl << "Reading: " << endl;FileStorage fs;fs.open(filename, FileStorage::READ); int itNr;//fs["iterationNr"] >> itNr;itNr = (int) fs["iterationNr"];cout << itNr;if (!fs.isOpened()){cerr << "Failed to open " << filename << endl;help(av);return 1;} FileNode n = fs["strings"]; // Read string sequence - Get nodeif (n.type() != FileNode::SEQ){cerr << "strings is not a sequence! FAIL" << endl;return 1;} FileNodeIterator it = n.begin(), it_end = n.end(); // Go through the nodefor (; it != it_end; ++it)cout << (string)*it << endl; n = fs["Mapping"]; // Read mappings from a sequencecout << "Two " << (int)(n["Two"]) << "; ";cout << "One " << (int)(n["One"]) << endl << endl; MyData m;Mat R, T; fs["R"] >> R; // Read cv::Matfs["T"] >> T;fs["MyData"] >> m; // Read your own structure_ cout << endl<< "R = " << R << endl;cout << "T = " << T << endl << endl;cout << "MyData = " << endl << m << endl << endl; //Show default behavior for non existing nodescout << "Attempt to read NonExisting (should initialize the data structure with its default).";fs["NonExisting"] >> m;cout << endl << "NonExisting = " << endl << m << endl;} cout << endl<< "Tip: Open up " << filename << " with a text editor to see the serialized data." << endl; return 0;
}

C++Python

from __future__ import print_function 
import numpy as np
import cv2 as cv
import sys 
def help(filename):print ('''{0} shows the usage of the OpenCV serialization functionality. \n\nusage:\npython3 {0} outputfile.yml.gz\n\nThe output file may be either in XML, YAML or JSON. You can even compress it\nby specifying this in its extension like xml.gz yaml.gz etc... With\nFileStorage you can serialize objects in OpenCV.\n\nFor example: - create a class and have it serialized\n- use it to read and write matrices.\n'''.format(filename)) 
class MyData:A = 97X = np.piname = 'mydata1234' def __repr__(self):s = '{ name = ' + self.name + ', X = ' + str(self.X)s = s + ', A = ' + str(self.A) + '}'return s def write(self, fs, name):fs.startWriteStruct(name, cv.FileNode_MAP|cv.FileNode_FLOW)fs.write('A', self.A)fs.write('X', self.X)fs.write('name', self.name)fs.endWriteStruct() def read(self, node):if (not node.empty()):self.A = int(node.getNode('A').real())self.X = node.getNode('X').real()self.name = node.getNode('name').string()else:self.A = self.X = 0self.name = '' 
def main(argv):if len(argv) != 2:help(argv[0])exit(1) # write R = np.eye(3,3)T = np.zeros((3,1)) m = MyData() filename = argv[1] s = cv.FileStorage(filename, cv.FileStorage_WRITE)# or:# s = cv.FileStorage()# s.open(filename, cv.FileStorage_WRITE) s.write('iterationNr', 100) s.startWriteStruct('strings', cv.FileNode_SEQ)for elem in ['image1.jpg', 'Awesomeness', '../data/baboon.jpg']:s.write('', elem)s.endWriteStruct() s.startWriteStruct('Mapping', cv.FileNode_MAP)s.write('One', 1)s.write('Two', 2)s.endWriteStruct() s.write('R_MAT', R)s.write('T_MAT', T) m.write(s, 'MyData') s.release() print ('Write Done.') # readprint ('\nReading: ')s = cv.FileStorage()s.open(filename, cv.FileStorage_READ) n = s.getNode('iterationNr')itNr = int(n.real()) print (itNr) if (not s.isOpened()):print ('Failed to open ', filename, file=sys.stderr)help(argv[0])exit(1) n = s.getNode('strings')if (not n.isSeq()):print ('strings is not a sequence! FAIL', file=sys.stderr)exit(1) for i in range(n.size()):print (n.at(i).string()) n = s.getNode('Mapping')print ('Two',int(n.getNode('Two').real()),'; ')print ('One',int(n.getNode('One').real()),'\n') R = s.getNode('R_MAT').mat()T = s.getNode('T_MAT').mat() m.read(s.getNode('MyData')) print ('\nR =',R)print ('T =',T,'\n')print ('MyData =','\n',m,'\n') print ('Attempt to read NonExisting (should initialize the data structure','with its default).')m.read(s.getNode('NonExisting'))print ('\nNonExisting =','\n',m) print ('\nTip: Open up',filename,'with a text editor to see the serialized data.') 
if __name__ == '__main__':main(sys.argv)

解释

这里我们只讨论 XML 和 YAML 文件输入。您的输出(及其各自的输入)文件可能只有这些扩展名之一,并且结构来自此。它们是可以序列化的两种数据结构:映射(如 STL 映射和 Python 字典)和元素序列(如 STL 向量)。它们之间的区别在于,在地图中,每个元素都有一个唯一的名称,您可以通过访问它的内容。对于序列,您需要遍历它们以查询特定项目。

XML/YAML 文件打开和关闭:

在将任何内容写入此类文件之前,您需要打开它,最后关闭它。OpenCV 中的 XML/YAML 数据结构是 cv::FileStorage 。要指定文件绑定到硬盘上的此结构,您可以使用其构造函数或以下函数的 open() 函数:

C++:

 FileStorage fs(filename, FileStorage::WRITE);// or:// FileStorage fs;// fs.open(filename, FileStorage::WRITE);

Python: 

 s = cv.FileStorage(filename, cv.FileStorage_WRITE)# or:# s = cv.FileStorage()# s.open(filename, cv.FileStorage_WRITE)

您使用的第二个参数中的任何一个都是一个常量,指定您可以对它们执行的操作类型:WRITE、READ 或 APPEND。文件名中指定的扩展名还决定了将使用的输出格式。如果指定扩展名(如 *.xml.gz*),输出甚至可能会被压缩。

当 cv::FileStorage 对象被销毁时,该文件将自动关闭。但是,您可以使用 release 函数显式调用此函数:

C++:

 fs.release(); // explicit close

Python:

 s.release()

文本和数字的输入和输出:

在C++中,数据结构使用 STL 库中的<<输出运算符。在 Python 中,改用 cv::FileStorage::write()。要输出任何类型的数据结构,我们首先需要指定其名称。我们只需将它的名称推送到 C++ 中的流即可做到这一点。在 Python 中,写函数的第一个参数是名称。对于基本类型,您可以按照以下值打印:

C++:

fs << "iterationNr" << 100;

Python:

 s.write('iterationNr', 100)

读入是一个简单的寻址(通过 [] 运算符)和强制转换操作,或者通过 >> 运算符读取。在 Python 中,我们使用 getNode() 进行寻址并使用 real() 

C++:

 int itNr;//fs["iterationNr"] >> itNr;itNr = (int) fs["iterationNr"];

Python:

 int itNr;//fs["iterationNr"] >> itNr;itNr = (int) fs["iterationNr"];

OpenCV 数据结构的输入/输出:

好吧,它们的行为与基本的 C++ 和 Python 类型完全相同:

c++: 

 Mat R = Mat_<uchar>::eye(3, 3),T = Mat_<double>::zeros(3, 1);fs << "R" << R; // cv::Matfs << "T" << T;fs["R"] >> R; // Read cv::Matfs["T"] >> T;

Python: 

 R = np.eye(3,3)T = np.zeros((3,1))s.write('R_MAT', R)s.write('T_MAT', T)R = s.getNode('R_MAT').mat()T = s.getNode('T_MAT').mat()

向量(数组)和关联映射的输入/输出:

如我之前提到的,我们也可以输出映射和序列(数组、向量)。同样,我们首先打印变量的名称,然后我们必须指定我们的输出是序列还是映射。

对于第一个元素之前的序列,请打印“[”字符,在最后一个元素之后打印“]”字符。使用 Python 时,调用 where is 或开始编写结构。调用以完成结构:

FileStorage.startWriteStruct(structure_name, struct_type)struct_typecv2.FileNode_MAPcv2.FileNode_SEQFileStorage.endWriteStruct()

c++: 

 fs << "strings" << "["; // text - string sequencefs << "image1.jpg" << "Awesomeness" << "../data/baboon.jpg";fs << "]"; // close sequence

Python: 

 s.startWriteStruct('strings', cv.FileNode_SEQ)for elem in ['image1.jpg', 'Awesomeness', '../data/baboon.jpg']:s.write('', elem)s.endWriteStruct()

对于映射,键值是相同的,但是现在我们使用“{”和“}”分隔符:

c++: 

 fs << "Mapping"; // text - mappingfs << "{" << "One" << 1;fs << "Two" << 2 << "}";

 Python:

 s.startWriteStruct('Mapping', cv.FileNode_MAP)s.write('One', 1)s.write('Two', 2)s.endWriteStruct()

为了从这些中读取数据,我们使用 cv::FileNode 和 cv::FileNodeIterator 数据结构。cv::FileStorage 类(或 Python 中的 getNode()函数)的 [] 运算符返回 cv::FileNode 数据类型。如果节点是顺序的,则可以使用 cv::FileNodeIterator 循环访问项。在 Python 中,at()函数可用于寻址序列的元素,size()函数返回序列的长度:

c++:

FileNode n = fs["strings"]; // Read string sequence - Get nodeif (n.type() != FileNode::SEQ){cerr << "strings is not a sequence! FAIL" << endl;return 1;} FileNodeIterator it = n.begin(), it_end = n.end(); // Go through the nodefor (; it != it_end; ++it)cout << (string)*it << endl;

Python: 

 n = s.getNode('strings')if (not n.isSeq()):print ('strings is not a sequence! FAIL', file=sys.stderr)exit(1) for i in range(n.size()):print (n.at(i).string())

对于映射,您可以再次使用 [] 运算符(Python 中的 at()函数)来访问给定的项目(或 >> 运算符):

c++:

 n = fs["Mapping"]; // Read mappings from a sequencecout << "Two " << (int)(n["Two"]) << "; ";cout << "One " << (int)(n["One"]) << endl << endl;

Python: 

 n = s.getNode('Mapping')print ('Two',int(n.getNode('Two').real()),'; ')print ('One',int(n.getNode('One').real()),'\n')

读取和写入您自己的数据结构。假设您有一个数据结构,例如:

C++:

class MyData
{
public:MyData() : A(0), X(0), id() {}
public: // Data Membersint A;double X;string id;
};

Python:

class MyData:def __init__(self):self.A = self.X = 0self.name = ''

 在 C++ 中,可以通过 OpenCV I/O XML/YAML 接口(就像 OpenCV 数据结构一样)通过在类内外添加读取和写入函数来序列化它。在 Python 中,您可以通过在类中实现读写函数来接近这一点。对于内部部分:

c++:

 void write(FileStorage& fs) const //Write serialization for this class{fs << "{" << "A" << A << "X" << X << "id" << id << "}";}void read(const FileNode& node) //Read serialization for this class{A = (int)node["A"];X = (double)node["X"];id = (string)node["id"];}

Python: 

 def write(self, fs, name):fs.startWriteStruct(name, cv.FileNode_MAP|cv.FileNode_FLOW)fs.write('A', self.A)fs.write('X', self.X)fs.write('name', self.name)fs.endWriteStruct() def read(self, node):if (not node.empty()):self.A = int(node.getNode('A').real())self.X = node.getNode('X').real()self.name = node.getNode('name').string()else:self.A = self.X = 0self.name = ''

在 C++ 和python中,需要在类之外添加以下函数定义:

C++:

static void write(FileStorage& fs, const std::string&, const MyData& x)
{x.write(fs);
}
static void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){if(node.empty())x = default_value;elsex.read(node);
}

在这里,您可以观察到,在读取部分中,我们定义了如果用户尝试读取不存在的节点会发生什么。在这种情况下,我们只返回默认的初始化值,但是更详细的解决方案是返回一个对象 ID 的减 1 值。

添加这四个函数后,使用 >> 运算符进行写入,使用 << 运算符进行读取(或为 Python 定义的输入/输出函数):

C++:

 MyData m(1);fs << "MyData" << m; // your own data structuresfs["MyData"] >> m; // Read your own structure_

Python: 

 m = MyData()m.write(s, 'MyData')m.read(s.getNode('MyData'))

 或者尝试阅读不存在的读取:

c++:

 cout << "Attempt to read NonExisting (should initialize the data structure with its default).";fs["NonExisting"] >> m;cout << endl << "NonExisting = " << endl << m << endl;

 Python:

 print ('Attempt to read NonExisting (should initialize the data structure','with its default).')m.read(s.getNode('NonExisting'))print ('\nNonExisting =','\n',m)

我们可以看到结果:

大多数情况下,我们只是打印出定义的数字。在主机的屏幕上,您可以看到:

Write Done. 
Reading:
100image1.jpg
Awesomeness
baboon.jpg
Two 2; One 1 
R = [1, 0, 0;0, 1, 0;0, 0, 1]
T = [0; 0; 0] 
MyData =
{ id = mydata1234, X = 3.14159, A = 97}Attempt to read NonExisting (should initialize the data structure with its default).
NonExisting =
{ id = , X = 0, A = 0} 
Tip: Open up output.xml with a text editor to see the serialized data.

在输出 xml 文件中可能看到的内容更有趣:

<?xml version="1.0"?>
<opencv_storage>
<iterationNr>100</iterationNr>
<strings>image1.jpg Awesomeness baboon.jpg</strings>
<Mapping><One>1</One><Two>2</Two></Mapping>
<R type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>u</dt><data>1 0 0 0 1 0 0 0 1</data></R>
<T type_id="opencv-matrix"><rows>3</rows><cols>1</cols><dt>d</dt><data>0. 0. 0.</data></T>
<MyData><A>97</A><X>3.1415926535897931e+000</X><id>mydata1234</id></MyData>
</opencv_storage>

或者 YAML 文件:

%YAML:1.0
iterationNr: 100
strings:- "image1.jpg"- Awesomeness- "baboon.jpg"
Mapping:One: 1Two: 2
R: !!opencv-matrixrows: 3cols: 3dt: udata: [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]
T: !!opencv-matrixrows: 3cols: 1dt: ddata: [ 0., 0., 0. ]
MyData:A: 97X: 3.1415926535897931e+000id: mydata1234

You may observe a runtime instance of this on the YouTube here .

参考文章:

1、《File Input and Output using XML and YAML files》----Bernát Gábor

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2904662.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

2023中国制造业标杆工厂数字化转型场景地图报告(可下载)

请前往星球下载&#xff08;可领取优惠券&#xff09;&#xff1a;https://t.zsxq.com/18gRm06pe

VsCode的json文件不允许注释的解决办法

右下角找到注释点进去 输入Files: Associations搜索出此项 改为项为*.json值为jsonc保存即可 然后会发现VsCode的json文件就允许注释了

[BT]BUUCTF刷题第10天(3.28)

第10天&#xff08;共3题&#xff09; Basic BUU SQL COURSE 1 打开网站看到右上角有个登录界面&#xff0c;怀疑是SQL注入 但是多次尝试都无果 通过看题解知道了还有一个隐藏网页&#xff08;content_detail.php&#xff09; 随便点一个测试新闻进去后点F12看网络&#xf…

SpringBoot+Prometheus+Grafana实现应用监控和报警

一、背景 SpringBoot的应用监控方案比较多&#xff0c;SpringBootPrometheusGrafana是目前比较常用的方案之一。它们三者之间的关系大概如下图&#xff1a; 关系图 二、开发SpringBoot应用 首先&#xff0c;创建一个SpringBoot项目&#xff0c;pom文件如下&#xff1a; <…

如何调试Clang源码

下载编译Clang 这个就直接去LLVM官网下载&#xff0c;然后编译好Clang就行&#xff0c;注意得debug模式&#xff0c;保存符号信息。 调试Clang 可以直接通过命令行来调试 #进入调试环境&#xff0c;这里的clang得是刚刚编译好的 lldb ./clang # r是运行&#xff0c;后面是正…

OpenHarmony实战开发-滑动容器组件Swiper的使用

介绍 本篇Codelab主要介绍了滑动容器组件Swiper的几种常见的应用场景&#xff0c;包括顶部导航、轮播图以及视频滑动播放。 相关概念 Swiper&#xff1a;滑动容器&#xff0c;提供子组件切换滑动的能力。Stack&#xff1a;堆叠容器&#xff0c;子组件按照顺序依次入栈&#x…

IC-随便记

1、移远通信---通信模组 物联网解决方案供应商&#xff0c;可提供完备的IoT产品和服务&#xff0c;涵盖蜂窝模组(5G/4G/3G/2G/LPWA)、车载前装模组、智能模组&#xff08;5G/4G/边缘计算&#xff09;、短距离通信模组(Wi-Fi&BT)、GNSS定位模组、卫星通信模组、天线等硬件产…

深圳区块链交易所app系统开发,撮合交易系统开发

随着区块链技术的迅速发展和数字资产市场的蓬勃发展&#xff0c;区块链交易所成为了数字资产交易的核心场所之一。在这个快速发展的领域中&#xff0c;区块链交易所App系统的开发和撮合交易系统的建设至关重要。本文将探讨区块链交易所App系统开发及撮合交易系统的重要性&#…

Unity3d使用Jenkins自动化打包(Windows)(一)

文章目录 前言一、安装JDK二、安装Jenkins三、Jenkins插件安装和使用基础操作 实战一基础操作 实战二 四、离线安装总结 前言 本篇旨在介绍基础的安装和操作流程&#xff0c;只需完成一次即可。后面的篇章将深入探讨如何利用Jenkins为Unity项目进行打包。 一、安装JDK 1、进入…

每日一题 --- 链表相交[力扣][Go]

链表相交 题目&#xff1a;面试题 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交**&#xff1a;** 题目数据 保证 整个链式结…

RabbitMQ3.x之四_RabbitMQ角色说明及创建用户与授权

RabbitMQ3.x之四_角色说明及创建用户与授权 文章目录 RabbitMQ3.x之四_角色说明及创建用户与授权1. 访问和授权1. Tags说明2. 命令行示例 2. 管理界面新建用户及访问授权1. 管理界面新建用户2. 管理界面中的授权说明3. guest用户不能远程登录提示 3. 创建用户1. 基本命令2. 实际…

【IP 组播】PIM-SM

目录 原理概述 实验目的 实验内容 实验拓扑 1.基本配置 2.配置IGP 3.配置PIM-SM 4.用户端DR与组播源端DR 5.从RPT切换到SPT 6.配置PIM-Silent接口 原理概述 PIM-SM 是一种基于Group-Shared Tree 的组播路由协议&#xff0c;与 PIM-DM 不同&#xff0c;它适合于组播组成…

京东云搭建幻兽帕鲁Palworld多人游戏联机服务器教程,1分钟开服

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云atengyun.…

[flink] flink macm1pro 快速使用从零到一

文章目录 快速使用 快速使用 打开 https://flink.apache.org/downloads/ 下载 flink 因为书籍介绍的是 1.12版本的&#xff0c;为避免不必要的问题&#xff0c;下载相同版本 解压 tar -xzvf flink-1.11.2-bin-scala_2.11.tgz启动 flink ./bin/start-cluster.sh打开 flink web…

Mac添加和关闭开机应用

文章目录 mac添加和关闭开机应用添加开机应用删除/查看 mac添加和关闭开机应用 添加开机应用 删除/查看 打开&#xff1a;系统设置–》通用–》登录项–》查看登录时打开列表 选中打开项目&#xff0c;点击“-”符号

STM32实现三个串口同时开启发送接收数据

程序目的&#xff1a; 实现STM32开通三个串口&#xff0c;每个串口都可以实现接收和发送数据。 注意事项&#xff1a; 编程时&#xff0c;严禁在中断函数中写入发送串口数据代码&#xff0c;否则会出错&#xff0c;具体原因不清楚&#xff08;有大佬知道的话帮我指出&#xff…

YOLOv9改进策略 | 损失函数篇 | InnerIoU、InnerMPDIoU二次创新损失函数助力小目标检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是InnerIoU以及包含其它二次创新的代码InnerCIoU、InnerMPDIoU等一些列利用Inner形成的二次创新损失函数&#xff0c;到此大家可能比较模糊为啥Inner能够和其他损失函数形成二次创新&#xff0c;Inner又是一个什么样的机制&#xff0c;开…

边缘计算与云计算总结

一. EdgeGallery 简介 MEC场景下的EdgeGallery是让资源边缘化&#xff0c;实时完成移动网络边缘的业务处理&#xff0c;MEC场景下的EdgeGallery让开发者能更便捷地使用 5G 网络能力&#xff0c;让5G能力在边缘触手可及。 EdgeGallery是由华为、信通院、中国移动、中国联通、…

网络原理-传输层-UDP报文结构

本文介绍UDP报文 有很多友友搞不清楚UDP报文的详细结构还有TCP的详细结构,所以专门分开来讲 以免弄混. 首先我们先看一下整个UDP结构,让大家有一个全方面的认识 下面我们来详细解释UDP报 16位源端口号(本机):就是2字节大小,16个二进制位. 16位目的端口号(目的机):也是2字节…

C++优先队列——priority_queue,函数对象,labmda表达式,pair等

头文件&#xff1a;#include<queue> 内部使用堆来实现&#xff0c;在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。 用法&#xff1a; priority_queue<int, vector<int>, greater<int>>q; 第一个参数为堆中存储的元素。 …