首页 > 解决方案 > vcap 无法打开 [udp @ 0x56378e8a76a0] 绑定失败:权限被拒绝

问题描述

我正在尝试使用带有 ipv6 地址的 opencv 中的 VideoCapture 函数从我的树莓派流式传输到我的 debian 虚拟机,但是当我尝试时,标题中出现错误。

我已经确认通过 netcat 和 mplayer 可以访问 ipv6 地址,具体如下:

Debian 主机:

网猫-l -6 -u 2222

树莓派:

/opt/vc/bin/raspivid -t 0 -w 300 -h 300 -hf -fps 20 -o - | nc -u(ipv6地址)2222

代码:

    VideoCapture vcap;

     const string videoStreamAddress = "udp://" + "(my Ipv6 address)" + ":2222";

 vcap.open(videoStreamAddress);

编辑:我已经确认 vcap.open 可以使用 127.0.0.1 但问题是它仍然无法使用我的 ipv6 地址

标签: opencvudpipv6

解决方案


以您指定的格式使用的 IPv6 地址<protocol>://需要用括号 ([]) 括起来。这最初在RFC 2732,URL 中文字 IPv6 地址的格式中指定,并在RFC 3896 中继续:统一资源标识符 (URI):通用语法

3.2.2. 主持人

权限的主机子组件由封装在方括号内的 IP 文字、点分十进制格式的 IPv4 地址或注册名称来标识。主机子组件不区分大小写。URI 中存在主机子组件并不意味着该方案需要访问 Internet 上的给定主机。在许多情况下,主机语法仅用于重用为 DNS 创建和部署的现有注册过程,从而获得全局唯一名称,而无需部署另一个注册表。然而,这样的使用也有其自身的成本:域名所有权可能会随着时间的推移而改变,原因是 URI 生产者没有预料到的。在其他情况下,主机组件中的数据标识与 Internet 主机无关的注册名称。我们使用名称“主机”

  host        = IP-literal / IPv4address / reg-name

host 的语法规则不明确,因为它不能完全区分 IPv4address 和 reg-name。为了消除语法歧义,我们应用“first-match-wins”算法:如果主机匹配 IPv4address 的规则,那么它应该被视为 IPv4 地址文字而不是 reg-name。尽管 host 不区分大小写,但生产者和规范化者应该为注册名称和十六进制地址使用小写字母,以保持统一,而仅使用大写字母进行百分比编码。

由 Internet 协议文字地址(版本 6 [RFC3513] 或更高版本)标识的主机通过将 IP 文字括在方括号(“[”和“]”)中来区分。这是 URI 语法中唯一允许使用方括号字符的地方。在对未来尚未定义的 IP 文字地址格式的预期中,实现可以使用可选的版本标志来明确指示这种格式,而不是依赖于启发式确定。

  IP-literal = "[" ( IPv6address / IPvFuture  ) "]"

  IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

版本标志不表示IP版本;相反,它表示文字格式的未来版本。因此,实现不得为下面描述的现有 IPv4 和 IPv6 文字地址形式提供版本标志。如果包含以“v”(不区分大小写)开头的 IP 文字的 URI(表示存在版本标志)被不知道该版本标志含义的应用程序取消引用,则应用程序应返回“不支持地址机制”的相应错误。

由 IPv6 文字地址标识的主机在方括号内表示,没有前面的版本标志。此处提供的 ABNF 是 [RFC3513] 中提供的 IPv6 文字地址的文本定义的翻译。此语法不支持 IPv6 范围的寻址区域标识符。

一个 128 位 IPv6 地址分为 8 个 16 位块。每个片段都以不区分大小写的十六进制数字表示,使用一到四个十六进制数字(允许前导零)。八个编码片段首先给出最重要的部分,用冒号字符分隔。可选地,最不重要的两部分可以改为以 IPv4 地址文本格式表示。可以省略地址中一个或多个连续的零值 16 位片段的序列,省略它们的所有数字并在它们的位置恰好留下两个连续的冒号来标记省略。

  IPv6address =                            6( h16 ":" ) ls32
              /                       "::" 5( h16 ":" ) ls32
              / [               h16 ] "::" 4( h16 ":" ) ls32
              / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
              / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
              / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
              / [ *4( h16 ":" ) h16 ] "::"              ls32
              / [ *5( h16 ":" ) h16 ] "::"              h16
              / [ *6( h16 ":" ) h16 ] "::"

  ls32        = ( h16 ":" h16 ) / IPv4address
              ; least-significant 32 bits of address

  h16         = 1*4HEXDIG
              ; 16 bits of address represented in hexadecimal

由 IPv4 文字地址标识的主机以点分十进制表示法(0 到 255 范围内的四个十进制数字的序列,用“.”分隔)表示,如 [RFC1123] 中通过引用 [RFC0952] 所描述的。请注意,在某些平台上可能会解释其他形式的点分符号,如第 7.4 节所述,但此语法只允许四个八位字节的点分十进制形式。

  IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

  dec-octet   = DIGIT                 ; 0-9
              / %x31-39 DIGIT         ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT     ; 200-249
              / "25" %x30-35          ; 250-255

由注册名称标识的主机是通常用于在本地定义的主机或服务名称注册表中查找的字符序列,尽管 URI 的特定于方案的语义可能需要使用特定的注册表(或固定名称表)来代替。最常见的名称注册机制是域名系统 (DNS)。用于在 DNS 中查找的注册名称使用 [RFC1034] 的第 3.5 节和 [RFC1123] 的第 2.1 节中定义的语法。这样的名称由一系列以“.”分隔的域标签组成,每个域标签以字母数字字符开头和结尾,还可能包含“-”字符。DNS 中完全限定域名的最右边的域标签可以跟一个“.”。

  reg-name    = *( unreserved / pct-encoded / sub-delims )

如果 URI 方案为主机定义了默认值,那么当主机子组件未定义或注册名称为空(零长度)时,该默认值适用。例如,“文件”URI 方案被定义为无权限、空主机和“本地主机”都表示最终用户的机器,而“http”方案认为缺少权限或空主机无效。

本规范不强制要求特定的注册名称查找技术,因此不会限制 regname 的语法超出互操作性所必需的范围。相反,它将注册名称语法一致性问题委托给执行 URI 解析的每个应用程序的操作系统,并且该操作系统决定它将允许什么用于主机识别。URI 解析实现可能使用 DNS、主机表、黄页、NetInfo、WINS 或任何其他系统来查找注册名称。但是,对于旨在具有全局范围的 URI,需要一个全局范围的命名系统,例如 DNS 完全限定的域名。URI 生产者应该使用符合 DNS 语法的名称,即使 DNS 的使用不是很明显,

reg-name 语法允许百分比编码的八位字节,以便以独立于底层名称解析技术的统一方式表示非 ASCII 注册名称。非 ASCII 字符必须首先根据 UTF-8 [STD63] 进行编码,然后必须对相应 UTF-8 序列的每个八位字节进行百分比编码才能表示为 URI 字符。生成 URI 的应用程序不得在主机中使用百分比编码,除非它用于表示 UTF-8 字符序列。当非 ASCII 注册名称代表旨在通过 DNS 解析的国际化域名时,必须在名称查找之前将该名称转换为 IDNA 编码 [RFC3490]。URI 生产者应该以 IDNA 编码提供这些注册名称,而不是百分比编码,


推荐阅读