【音视频第14天】webRTC协议(1)

news2025/1/4 17:36:56

目录

  • 协议
    • ICE
    • STUN
    • NAT
    • TURN
    • SDP
      • SDP结构
  • Signaling and Connecting
    • Signaling: How peers find each other in WebRTC
    • Connecting and NAT Traversal with STUN/TURN
  • Signaling
    • sdp协议
    • WebRTC如何使用sdp
    • WebRTC会话示例
  • Connecting
    • 为什么WebRTC需要一个专用的子系统来连接?
    • Networking real-world constraints
  • NAT Mapping
    • 创建映射
    • 映射创建行为
    • 映射过滤行为
    • 映射刷新
  • STUN
    • Protocol Structure
    • 创建 NAT 映射
    • 确定 NAT 类型

协议

ICE

Interactive Connectivity Establishment (ICE)是一个框架,能让web浏览器与对面进行连接。
从a端到b端不能直接建立连接原因有很多。

  1. 它需要绕过会阻止建立连接的防火墙
  2. 如果你的设备没有公共IP地址,那么它需要提供给你唯一的地址
  3. 如果你的路由器不允许直接与对端连接,那么需要通过服务器中转数据。
    ICE使用STUN和/或TURN服务器来完成此任务,如下所述。

STUN

Session Traversal Utilities for NAT (STUN)是一种协议,用于发现您的公共地址,并确定路由器中阻止与对端直接连接的任何限制。
客户端将向Internet上的STUN服务器发送一个请求,STUN服务器将回复客户端的公共地址以及在路由器的NAT之后是否可以访问客户端。
可以了就可以直接访问了。
在这里插入图片描述

NAT

Network Address Translation (NAT)用于为您的设备提供一个公共IP地址。路由器将有一个公共IP地址,连接到路由器的每个设备将有一个私有IP地址。请求将从设备的私有IP转换为路由器的具有唯一端口的公共IP。这样你就不用每个设备都有一个唯一的公共IP,但仍然可以在互联网上被发现。
对于谁能连接上已经在互联网上的设备,路由器对此有限制。这可能意味着,即使我们拥有STUN服务器找到的公共IP地址,也不是任何人都可以创建连接。在这种情况下,我们需要使用TURN。

TURN

一些使用NAT的路由器采用“对称NAT”的限制方法。这意味着路由器将只接受来自你之前连接过的对端的连接。【也就是在对称NAT下,只能连接之前连接了的对端】
Traversal Using Relays around NAT (TURN)意味着绕过对称NAT的限制,通过打开与TURN服务器的连接并通过该服务器中转所有信息。您将创建一个与TURN服务器的连接,并告诉所有对等点向服务器发送数据包,然后这些数据包将被转发给您。这显然会带来一些成本开销,所以只有在没有其他替代方案的情况下才会使用它。
在这里插入图片描述

SDP

Session Description Protocol (SDP)是一种标准,用于描述连接的多媒体内容,如分辨率、格式、编解码器、加密等,以便对等端在数据传输时能够相互理解。从本质上讲,这是描述内容的元数据,而不是媒体内容本身。
从技术上讲,SDP并不是真正的协议,而是一种用于描述设备间共享媒体的连接的数据格式
编写SDP文档远远超出了本文档的范围;然而,这里有一些事情值得注意:

SDP结构

SDP由一行或多行UTF-8文本组成,每行以一个字符类型开头,后面跟着等号(“=”),然后是包含值或描述的结构化文本,其格式取决于类型。以给定字母开头的文本行通常被称为“字母行”。例如,提供媒体描述的行具有“m”类型,因此这些行被称为“m-line”。

Signaling and Connecting

Signaling: How peers find each other in WebRTC

【通过带外的信令,传递SDP】
当WebRTC代理启动时,它不知道它要与谁通信,也不知道他们要通信什么。Signaling解决了这个问题。Signaling用于引导调用,允许两个独立的WebRTC代理开始通信。
Signaling使用一种称为SDP(会话描述协议)的协议。每个SDP消息由键/值对组成,并包含一个“media sections”列表。两个WebRTC代理交换的SDP包含如下细节:

  • 代理可访问的ip和ports
  • 代理希望发送的音频和视频轨道的数量。
  • 每个代理支持的音频和视频编解码器。
  • 连接时使用的值(uFrag/uPwd)。
  • 安全时使用的值(证书指纹)。
    需要注意的是,信令通常发生在“带外out-of-band”,这意味着应用程序通常不使用WebRTC本身来交换信令消息。任何适合于发送消息的体系结构都可以在连接的对等体之间中转sdp,许多应用程序将简单地使用它们现有的基础结构(例如REST端点、WebSocket连接或身份验证代理)来促进适当的客户机之间的sdp交易。

Connecting and NAT Traversal with STUN/TURN

【通过ICE建立连接】
一旦两个WebRTC代理交换了sdp,它们就有了足够的信息来尝试相互连接。为了实现这种连接,WebRTC使用了另一种称为ICE(交互式连接建立)的成熟技术。
ICE是一种早于WebRTC的协议,允许在没有中央服务器的情况下在两个代理之间建立直接连接。这两个代理可能在同一个网络上,也可能在世界的另一端。
ICE可以实现直接连接,但真正连接过程涉及一个叫做“NAT遍历”的概念和STUN/TURN服务器的使用。
当两个代理成功建立ICE连接时,WebRTC将进入下一步;为在它们之间共享音频、视频和数据建立加密传输。

Signaling

当您创建WebRTC代理时,它对另一个对端一无所知。它不知道它将与谁连接,也不知道他们将发送什么。我们使用信令引导调用。在这些值交换之后,WebRTC代理可以直接相互通信。信令信息只是文本。WebRTC并不关心他们是如何被运输的。它们通常通过Websockets共享,但这不是必需的。
WebRTC使用一种称为sdp协议。通过该协议,两个WebRTC端点将共享建立连接所需的所有状态。协议本身易于阅读和理解。复杂性来自于理解WebRTC填充的所有值**。这个协议不是专门针对WebRTC的**。WebRTC实际上只利用了sdp协议的一个子集,所以我们只学习我们需要的部分。在我们理解该协议之后,我们将继续讨论它在WebRTC中的应用。

sdp协议

sdp协议在RFC 8866中定义。它是一个键/值协议,每个值后面都有换行符。它感觉类似于INI文件。一个会话描述包含0个或多个媒体描述。在思想上,你可以把它建模为一个会话描述,其中包含一个媒体描述数组。
媒体描述通常映射到一个单一的媒体流。因此,如果你想用三个视频流和两个音频轨道来描述一个会话,你将有五个媒体描述。
会话描述中的每一行都以一个字符开始,这是你的键。然后它后面会跟着一个等号。等号后面就是值。在该值完成后,将有一个换行符。
会话描述协议定义了所有有效的密钥。您只能使用协议中定义的字母作为密钥。这些键都有重要的意义,后面会解释。以下会话描述:

a=my-sdp-value
a=second-value

你有两条线。第一行值为my-sdp-value,第二行值为second-value。
WebRTC并不使用会话描述协议定义的所有键值。只有在RFC 8829中定义的JavaScript会话建立协议(JSEP)中使用的键是重要的。下面的七个关键是你现在只需要了解的:

v - Version, should be equal to 0.
o - Origin, 包含一个唯一的ID,用于重新协商.
s - Session Name, should be equal to -.
t - Timing, should be equal to 0 0.
m - Media Description (m=<media> <port> <proto> <fmt> ...), described in detail below.
a - Attribute, 一个自由文本字段。这是WebRTC中最常见的一行。
c - Connection Data, should be equal to IN IP4 0.0.0.0.

“会话描述”可以包含无限个“Media Description”。
Media Description定义包含一个格式列表。这些格式映射到RTP有效负载类型。然后,实际的编解码器由Media Description中值为rtpmap的Attribute定义。每个媒体描述可以包含无限数量的属性。
以这段Session Description摘录为例:

v=0
m=audio 4000 RTP/AVP 111
a=rtpmap:111 OPUS/48000/2
m=video 4000 RTP/AVP 96
a=rtpmap:96 VP8/90000
a=my-sdp-value

您有两个媒体描述,一个是fmt 111类型的音频,一个是96格式的视频。第一个媒体描述只有一个属性。此属性将负载类型111映射到Opus。第二个Media Description有两个属性。第一个属性将Payload Type 96映射为VP8,第二个属性是my-sdp-value。
下面将我们讨论过的所有概念结合在一起。这些都是WebRTC使用的会话描述协议的所有特性。

v=0
o=- 0 0 IN IP4 127.0.0.1
s=-
c=IN IP4 127.0.0.1
t=0 0
m=audio 4000 RTP/AVP 111
a=rtpmap:111 OPUS/48000/2
m=video 4002 RTP/AVP 96
a=rtpmap:96 VP8/90000

v, o, s, c, t被定义,但它们不影响WebRTC会话。
你有两个媒体描述。一个是音频类型,一个是视频类型。
每一个都有一个属性。此属性配置RTP管道的详细信息。

WebRTC如何使用sdp

WebRTC使用offer/answer模型。这意味着一个WebRTC代理发出“offer”开始呼叫,如果它愿意接受所提供的内容,WebRTC 另一端“answers”。这使应答者有机会在媒体描述中拒绝不支持的编解码器。这就是两端如何理解它们想交换的格式。
Transceivers 是用于发送和接收的
Transceivers 是WebRTC特定的概念,你将在API中看到。它将“Media Description”暴露给JavaScript API。每个Media Description都成为一个Transceivers。每次你创建一个Transceivers,一个新的“Media Description就会被添加到本地Session Description中。WebRTC中的每个Media Description都有一个方向属性。这允许WebRTC代理声明“我将把这个编解码器发送给你,但我不愿意接受任何回报”。有四个有效值:send recv sendrecv inactive
WebRTC使用的SDP值
在WebRTC代理的会话描述中常见属性的列表。这些值控制着子系统。
group:BUNDLE:Bundling是在一个连接上运行多种类型的流量的行为。一些WebRTC实现为每个媒体流使用专用连接。最好是Bundling。
fingerprint:sha-256:这是对等体用于DTLS的证书的hash。DTLS握手完成后,将其与实际证书进行比较,以确认您正在与期望的对象通信。
**setup:**这控制DTLS代理行为。这决定了在ICE连接之后,它是作为客户机还是服务器运行。可能取值为:

  • setup:active -作为DTLS客户端运行。
  • setup:passive -作为DTLS服务器运行。
  • setup:actpass -让其他WebRTC代理选择。
    **mid:**识别会话描述中的媒体流。
    ice-ufrag:这是ICE Agent的用户分片值。用于对ICE Traffic进行认证。
    ice-pwd:这是 ICE Agent的密码。用于对ICE Traffic进行认证。
    rtpmap:此值用于将特定的编解码器映射到RTP有效负载类型。有效负载类型不是静态的,因此对于每个调用,提供程序决定每个编解码器的有效负载类型。
    fmtp:为一个有效负载类型定义附加值。这对于传达特定的视频配置文件或编码器设置非常有用。
    **candidate:**这是一个来自ICE Agent的ICE Candidate。这是WebRTC Agent 可用的一个可能地址。这些将在下一章详细解释。
    ssrc :一个同步源(SSRC)定义了一个单一的媒体流轨迹。
    label:是这个单独流的ID。mslabel是容器的ID,容器里面其中可以有多个流。

WebRTC会话示例

下面是WebRTC客户端生成的完整会话描述:

v=0
o=- 3546004397921447048 1596742744 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 0F:74:31:25:CB:A2:13:EC:28:6F:6D:2C:61:FF:5D:C2:BC:B9:DB:3D:98:14:8D:1A:BB:EA:33:0C:A4:60:A8:8E
a=group:BUNDLE 0 1
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 0.0.0.0
a=setup:active
a=mid:0
a=ice-ufrag:CsxzEWmoKpJyscFj
a=ice-pwd:mktpbhgREmjEwUFSIJyPINPUhgDqJlSd
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
a=ssrc:350842737 cname:yvKPspsHcYcwGFTw
a=ssrc:350842737 msid:yvKPspsHcYcwGFTw DfQnKjQQuwceLFdV
a=ssrc:350842737 mslabel:yvKPspsHcYcwGFTw
a=ssrc:350842737 label:DfQnKjQQuwceLFdV
a=msid:yvKPspsHcYcwGFTw DfQnKjQQuwceLFdV
a=sendrecv
a=candidate:foundation 1 udp 2130706431 192.168.1.1 53165 typ host generation 0
a=candidate:foundation 2 udp 2130706431 192.168.1.1 53165 typ host generation 0
a=candidate:foundation 1 udp 1694498815 1.2.3.4 57336 typ srflx raddr 0.0.0.0 rport 57336 generation 0
a=candidate:foundation 2 udp 1694498815 1.2.3.4 57336 typ srflx raddr 0.0.0.0 rport 57336 generation 0
a=end-of-candidates
m=video 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=setup:active
a=mid:1
a=ice-ufrag:CsxzEWmoKpJyscFj
a=ice-pwd:mktpbhgREmjEwUFSIJyPINPUhgDqJlSd
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=ssrc:2180035812 cname:XHbOTNRFnLtesHwJ
a=ssrc:2180035812 msid:XHbOTNRFnLtesHwJ JgtwEhBWNEiOnhuW
a=ssrc:2180035812 mslabel:XHbOTNRFnLtesHwJ
a=ssrc:2180035812 label:JgtwEhBWNEiOnhuW
a=msid:XHbOTNRFnLtesHwJ JgtwEhBWNEiOnhuW
a=sendrecv

以下是我们从这条信息中了解到的:
我们有两个媒体部分,一个音频部分和一个视频部分。
它们都是sendrecv收发器。我们得到了两个流,我们可以发送两个回去。
我们有ICE候选人和身份验证详细信息,因此我们可以尝试连接。
我们有一个证书指纹,所以我们可以进行安全通话。

Connecting

为什么WebRTC需要一个专用的子系统来连接?

目前部署的大多数应用程序都建立 client/server连接。客户端/服务器连接要求服务器有一个稳定的已知传输地址。客户端与服务器连接,服务器响应。

WebRTC不使用 client/server 模型,它建立点对点(P2P)连接。在P2P连接中,创建连接的任务平均分配给两端。这是因为WebRTC中的传输地址(IP和端口)不能被假定,甚至可能在会话期间发生变化。WebRTC将尽可能地收集所有信息,并将竭尽全力实现两个WebRTC代理之间的双向通信。

不过,建立点对点连接可能很困难。这些代理可能位于不能直连的不同网络中。在存在直连的情况下,您仍然可能遇到其他问题。在某些情况下,您的客户端不使用相同的网络协议(UDP <-> TCP)或可能使用不同的IP版本(IPv4 <-> IPv6)

尽管在建立P2P连接时存在这些困难,但由于WebRTC提供的以下属性,您获得了优于传统客户端/服务器技术的优势。

  1. Reduced Bandwidth Costs
    因为媒体通信直接发生在对等点之间,你不需要付费,也不需要托管一个单独的服务器来转发媒体。
  2. Lower Latency
    低延迟:Lower Latency
    直连更快捷,当通过服务器运行所有内容时,传输速度会变慢
    3.Secure E2E Communication
    端到端安全通信:直接交流更安全。由于用户不会通过您的服务器路由数据,因此他们甚至不需要相信您不会解密数据

上面描述的过程称为交互式连接建立(ICE)。另一个早于WebRTC的协议。ICE是一种试图找到两个ICE代理之间通信的最佳方式的协议。每个ICE Agent 公布了可以到达的方式,这些被称为candidates。candidates本质上是agent的传输地址,它认为另一个对端可以到达该传输地址。然后,ICE决定candidates的最佳组合。

Networking real-world constraints

ICE就是要克服现实世界网络的限制。在探讨解决方案之前,让我们先谈谈实际问题

  1. 不在同一个网络
    在这里插入图片描述
    对于同一网络中的主机来说,连接非常容易。192.168.0.1 ->192.168.0.2很容易做到。这两台主机可以在没有任何外部帮助的情况下相互连接。
    然而,使用路由器B(routerB)的主机没有办法直接访问路由器a(routerA)后面的任何东西,你如何区分路由器a(routerA)后面的192.168.0.1和路由器B(routerB)后面的相同IP ? 它们是私有ip 。使用路由器B(routerB)的主机可以直接向路由器A(routerA)发送流量,但请求将在那里结束。路由器A(routerA)如何知道它应该把消息转发给哪台主机?
  2. 协议限制
    一些网络根本不允许UDP流量,或者可能他们不允许TCP。一些网络可能有非常低的MTU(最大传输单元)。网络管理员可以改变很多变量,从而使通信变得困难。
  3. 防火墙/IDS规则
    另一个是“深度包检测”和其他智能过滤。一些网络管理员会运行试图处理每个数据包的软件。很多时候,这个软件不理解WebRTC,所以它会阻止它,因为它不知道该做什么,例如,将WebRTC数据包视为任意端口上的可疑UDP数据包,而不是白名单。

NAT Mapping

NAT(网络地址转换)映射是使WebRTC的连通性成为可能。这就是WebRTC允许完全不同子网中的两端通信的方式,解决了上述“不在同一个网络”的问题。虽然Agent 1和Agent 2他们在不同的网络中,但是是可以通信的。
在这里插入图片描述
为了实现这种通信,需要建立一个NAT映射。Agent 1通过7000端口与Agent 2建立WebRTC连接。这将创建192.168.0.1:7000到5.0.0.1:7000的绑定。这允许Agent 2通过发送到5.0.0.1:7000的报文到达Agent 1。这个示例中的NAT映射就像在路由器中进行端口转发的自动版本。

NAT映射的缺点是没有单一形式的映射(例如静态端口转发),并且网络之间的行为不一致。互联网服务提供商和硬件制造商可能以不同的方式做到这一点。【看不太懂NAT映射的缺点】在某些情况下,网络管理员甚至会禁用它。好消息是,所有的行为都是可以理解和观察到的,因此ICE代理能够确认它创建了一个NAT映射,以及映射的属性。描述这些行为的文档是RFC 4787。

创建映射

创建映射是最简单的部分。当你发送一个包到你的网络之外的地址时,一个映射就被创建了。NAT映射只是一个临时的公网IP和端口,由您的NAT分配。出站消息将被重写,其源地址由新的映射地址给出。如果一条消息被发送到映射,它将自动路由回创建它的NAT内的主机。映射的细节是它变得复杂的地方。

映射创建行为

映射创建分为三个不同的类别:

  1. 端点独立映射
    在NAT内部为每个发送方创建一个映射。如果向两个不同的远端地址发送两个报文,NAT映射将被重用。两个远程主机将看到相同的源IP和端口。如果远程主机响应,它将被发送回同一个本地侦听器。
    这是最好的情况。对于工作调用,至少有一方必须是这种类型。
  2. 地址依赖映射
    每次发送一个数据包到一个新地址时都会创建一个新的映射。如果向不同的主机发送两个报文,会产生两个映射。如果向同一个远端主机发送两个数据包,但目的端口不同,则不会创建新的映射。
  3. 地址和端口依赖映射
    如果远端IP或端口不同,则创建新的映射。如果向同一个远端主机发送两个数据包,但目的端口不同,则会创建一个新的映射。

映射过滤行为

映射过滤是关于谁可以使用映射的规则。它们分为三个类似的类别:

  1. 端点独立过滤
    任何人都可以使用映射。您可以与多个其他对等点共享映射,它们都可以向它发送流量。
  2. 地址相关过滤
    只有创建映射的主机可以使用该映射。如果您向主机A发送数据包,则只能从同一主机获得响应。如果主机B试图向该映射发送一个数据包,它将被忽略。
  3. 地址和端口依赖过滤
    只有为其创建映射的主机和端口才能使用该映射。如果你发送一个包到a:5000,你只能从同一个主机和端口得到响应。如果A:5001试图向该映射发送一个数据包,它将被忽略。

映射刷新

如果一个映射5分钟没有使用,建议销毁它。这完全取决于ISP或硬件制造商。

STUN

STUN(NAT 会话传输实用程序)是一种用来配合 NAT 使用的协议。这是 WebRTC(和 ICE!)之前的另一项技术。它由RFC 8489定义,该文件还定义了 STUN 数据包结构。STUN 协议也在 ICE/TURN 中被使用。

STUN 很有用,因为它允许以编程方式创建 NAT 映射。在 STUN 之前,我们能够创建 NAT 映射,但是我们不知道映射的 IP 和端口是什么!STUN 不仅使你能够创建映射,还可以让你获取映射的详细信息,你可以他人分享这些详细信息,然后他们便可以通过你刚刚创建的映射向你传回数据。

让我们从对 STUN 的基本描述开始。稍后,我们再将话题扩展到 TURN 和 ICE 的用法。现在,我们只打算描述请求 / 响应流程来创建映射。然后,我们将讨论如何获取该映射的详细信息以便与他人共享。当你在 ICE URLs 中有一个用于 WebRTC PeerConnection 的 stun: 服务器时,此过程就会发生。简而言之,STUN 向 NAT 外部的 STUN 服务器发送请求,服务器返回其在请求中观察到的内容,STUN 根据这些内容来帮助 NAT 后面的端点找出已创建的映射。

Protocol Structure

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0|     STUN Message Type     |         Message Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Magic Cookie                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                     Transaction ID (96 bits)                  |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             Data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

STUN 消息类型
每个 STUN 数据包都有一个类型。目前,我们仅关心以下几种:

  • Binding Request - 0x0001
  • Binding Response - 0x0101
    为了创建一个 NAT 映射,我们发出一个 Binding Request。然后服务器回应一个 Binding Response

消息长度
这就是 Data 段的长度。这一段中包含由消息类型所定义的任意数据。

Magic Cookie
指的是固定值 0x2112A442,以网络字节顺序发送。这个值有助于将 STUN 流量与其他协议区分开。

交互(Transaction)ID
一个 96-bit 的标识符,用于唯一标识一个请求 / 响应对。这可以帮助你配对请求和响应。

数据
数据将包含一个 STUN 属性的列表。一个 STUN 属性具有以下结构:

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Type                  |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Value (variable)                ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

STUN Binding Request 不使用任何属性。这意味着一个STUN Binding Request仅包含 header。

STUN Binding Response 使用一个 XOR-MAPPED-ADDRESS (0x0020)。此属性包含一个 IP 和一个端口。这正是所创建的 NAT 映射的 IP 和端口!

创建 NAT 映射

使用 STUN 创建 NAT 映射只需要发送一个请求。你向 STUN 服务器发送一个 STUN Binding Request。然后,STUN 服务器回应一个 STUN Binding Response。 该 STUN Binding Response 将包含映射地址。映射地址是 STUN 服务器看到你的方式,也是你的 NAT 映射。 如果你希望某人向你发送数据包,那么你应该共享该映射地址。

人们还会将映射地址称为公网 IP 或 Server Reflexive Candidate。

确定 NAT 类型

不幸的是,映射地址可能并非在所有情况下都可用。如果是地址相关的映射,则只有 STUN 服务器才能将流量发送回给你。如果你共享它,那么另一个 peer 尝试向该地址发送的消息将被丢弃。这使得该 peer 无法与别的 peer 交流。如果 STUN 服务器还可以为你将数据包转发给对端 peer,你可能会发现地址相关的映射问题实际上是可以解决的!这也就是下面将要说到的 TURN 解决方案。

RFC 5780定义了一种方法,可以运行一个测试来确定你的 NAT 类型。这很有用,因为你可能会提前知道是否可以进行直接连接。

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

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

相关文章

配置 Zabbix Server 监控 Kafka 集群

目录 第一章.环境安装部署 第一章.环境安装部署 1.1安装卡夫卡集群跟zabbix 第二章操作步骤 2.1.记录集群 Zabbix 监控节点地址 2.2.在kafka三个节点安装安装 zabbix-agent2 2.3在 Web 页面中添加 agent 主机 第一章.环境安装部署 1.1安装卡夫卡集群跟zabbix systemctl…

2023年想学习编程语言,该选哪种?

2023年想学习编程语言&#xff0c;该选哪种&#xff1f;在计算机广泛运用于社会的各个行业领域乃至生活日常每个角落的今天&#xff0c;选择学习一门计算机语言真的很不错&#xff0c;它会让你的生活从此与众不同&#xff0c;拥有另一番光景的未来。 根据最新的编程语言排行榜…

聚焦运营商信创运维,美信时代监控易四大亮点值得一试!

2021年11月《“十四五”信息通信行业发展规划》提出&#xff0c;到2025年&#xff0c;我国将建立高速泛在、集成互联、智能绿色、安全可靠的新型数字基础设施体系。 此《规划》让我国运营商信创进一步加速&#xff0c;中国移动、中国电信、中国联通等都先后加入信创大军&#x…

尚硅谷大数据技术Scala教程-笔记05【模式匹配、异常、隐式转换、泛型、scala总结】

视频地址&#xff1a;尚硅谷大数据技术之Scala入门到精通教程&#xff08;小白快速上手scala&#xff09;_哔哩哔哩_bilibili 尚硅谷大数据技术Scala教程-笔记01【Scala课程简介、Scala入门、变量和数据类型、运算符、流程控制】尚硅谷大数据技术Scala教程-笔记02【函数式编程】…

性能测试简介

性能测试是通过模拟真实的用户&#xff0c;对软件或系统进行操作&#xff0c;查看其响应时间、响应速度、负载能力等。并分析在不同的业务需求下&#xff0c;系统的负载情况是否满足要求。 性能测试主要从两个方面进行&#xff1a;一方面是性能测试本身&#xff0c;包括压力测试…

【Vue-cli】前端工程化环境准备

一、知识点整理 1、Vue-cli 是Vue官方提供的一个脚手架&#xff0c;用于快速生成一个 Vue 的项目模板。 2、Vue-cli提供了如下功能: 1&#xff09;统一的目录结构 2&#xff09;本地调试 3&#xff09;热部署 4&#xff09;单元测试 5&#xff09;集成打包上线 3、需安装依赖…

2023年最新网络安全渗透工程师面试题汇总!不看亏大了!

技术面试问题 CTF 说一个印象深刻的CTF的题目 Padding Oracle->CBC->密码学(RSA/AES/DSA/SM) CRC32 反序列化漏洞 sql二次注入 第一次进行数据库插入数据的时候&#xff0c;仅仅只是使用了 addslashes 或者是借助get_magic_quotes_gpc 对其中的特殊字符进行了转义&…

Java中的文件操作

Java中通过java.io.File类对一个文件&#xff08;包含目录&#xff09;进行抽象的描述。注意有File对象&#xff0c;并不代表真实存在该文件。 1.File概述 我们先看看File类中的常见属性、构造方法和方法 1.1属性 修饰符及类型属性说明static StringpathSeparator依赖系统的…

利用ffmpeg源码安装+vscode开发环境搭建详解

前言&#xff1a; 大家好&#xff0c;今天给大家分享一篇ffmpeg开发环境的搭建&#xff0c;我在很早之前也给搭建过ffmpeg源码的安装&#xff0c;但是并没有给大家去搭建开发环境&#xff0c;而且当时的版本也比较老&#xff0c;很多细节问题没有给大家展示如何解决&#xff01…

win11破解以开启多用户同时登陆

1、简述 背景就是有一台电脑&#xff0c;windows11的专业版&#xff0c;上面有一套软件&#xff0c;但是这台电脑还有人需要用。电脑配置还不错&#xff0c;所以就想在创建一个账户&#xff0c;让需要用那套软件的人远程登陆使用。 步骤还不少&#xff0c;有一丢丢啰嗦。 2、首…

IP-GUARD如何通过设备管控策略单独禁用或启用笔记本插SD卡?

sd卡可以通过外置读卡器或者笔记本自带的sd卡槽进行插入使用,我们可以通过设备控制策略禁止sd插入的设备来实现控制; 在控制台-策略-设备控制: 动作:禁止/允许 设备描述:读卡器的设备描述(查看方法参考问题 2 ) 读卡器的描述信息可以在控制面板-设备管理中,usb相关的设…

springcloud-openFeign简单梳理

OpenFeign openFeign是springcloud中&#xff0c;服务间进行调用的常用方式。了解它&#xff0c;可以更好的处理服务间调用问题。 EnableFeignClients Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) Documented Import(FeignClientsRegistrar.class) public …

LTC6268-10 4GHz 超低偏置电流 FET 输入运算放大器

LTC6268-10是一个运算放大器 具有低输入偏置电流和低输入电容。它还具有低输入参考电流噪声和电压噪声。这使得它成为高速跨组放大器和高阻抗传感器放大电路的理想选择。其为去补偿型运放&#xff0c;具有数值为 10 的稳定增益。 该器件工作在 3.1V 至 5.25V 电源&#xff0c;每…

Android View的坐标获取详解以及动画坐标分析

1、介绍 在平面图形中&#xff0c;图形都是由点坐标确定的。同样&#xff0c;Android的设备屏幕也是一个&#xff0c;如果非3D图形&#xff0c;正常的view就是一个二维坐标 参考View屏幕的左上角的坐标A(0,0),如果屏幕的宽为:width,高&#xff1a;height 那么右下角的坐标是D(…

【C/C++】使用C++和Direct3D (d3d)获取屏幕截图并根据传入分辨率进行缩放图片大小

目录 一&#xff0c;函数清单 1.Direct3DCreate9 函数 2.IDirect3D9::CreateDevice 方法 3.IDirect3DDevice9::GetDisplayMode 方法 4.IDirect3DDevice9::CreateOffscreenPlainSurface 方法 5.IDirect3DDevice9::GetFrontBufferData 方法 6.IDirect3DDevice9::D3DXLoadS…

Zookeeper工作原理

一 Zookeeper是什么 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;它是集群的管理者&#xff0c;监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终&#xff0c;将简单易…

【Spring】我抄袭了Spring,手写一套MySpring框架。。。

这篇博客实现了一个简单版本的Spring&#xff0c;主要包括Spring的Ioc和Aop功能 文章目录这篇博客实现了一个简单版本的Spring&#xff0c;主要包括Spring的Ioc和Aop功能&#x1f680;ComponentScan注解✈️Component注解&#x1f681;在spring中ioc容器的类是ApplicationConte…

迅为4412开发板Qt 界面切换

本节通过实验介绍通过创建窗口对象的方式实现界面切换&#xff1a; 步骤一&#xff1a; 在主界面 ui 文件添加 pushButton 按钮&#xff0c; 然后新建一个窗口&#xff0c;工程下创建新的 Qt 设计师界面类&#xff0c;如图 &#xff1a; 我们选择 Widget&#xff0c;用户可以根…

logstash+elasticsearch+Kibana(ELK)日志收集

文章目录一.安装elasticsearch二. 安装kibana三.配置logstash四.springboot整合logstash五.spring整合Elastic Search六. 定时清理不要一股脑执行以下语句,请观察修改要修改的地方 注意给logstash,elasticsearch,kibana释放端口,云服务器提供商和系统的端口 一.安装elasticsea…

为什么许多人吐槽C++11,那些语法值得我们学习呢?

致前行的人&#xff1a; 人生像攀登一座山&#xff0c;而找寻出路&#xff0c;却是一种学习的过程&#xff0c;我们应当在这过程中&#xff0c;学习稳定冷静&#xff0c;学习如何从慌乱中找到生机。 目录 1.C11简介 2.统一的列表初始化 2.1 &#xff5b;&#xff5d;初始化 …