aioice里面candidate固定UDP端口测试

news2024/12/22 8:03:35

环境:

aioice0.9.0

问题描述:

aioice里面candidate固定UDP端口测试

解决方案:

/miniconda3/envs/nerfstream/lib/python3.10/site-packages/aioice

import hashlib
import ipaddress
import random
from typing import Optional
import logging

# 配置日志级别,默认为 INFO,可改为 DEBUG 查看详细调试信息
logging.basicConfig(level=logging.INFO)

class Candidate:
    """
    表示一个 ICE 候选者,包括固定端口功能和多种优化。
    """
    FIXED_PORT = 59990  # 定义固定端口

    def __init__(
        self,
        foundation: str,
        component: int,
        transport: str,
        priority: int,
        host: str,
        port: Optional[int] = None,  # 端口可以是 None,将被替换为固定端口
        type: str = "host",
        related_address: Optional[str] = None,
        related_port: Optional[int] = None,
        tcptype: Optional[str] = None,
        generation: Optional[int] = None,
    ) -> None:
        """
        初始化候选者对象,并强制使用固定端口。
        """
        self.foundation = foundation
        self.component = component
        self.transport = transport
        self.priority = priority
        self.host = host
        self.port = self.get_fixed_port() if port is None else port  # 设置为固定端口或提供的端口
        self.type = type
        self.related_address = related_address
        self.related_port = related_port
        self.tcptype = tcptype
        self.generation = generation

        # 输出候选者信息到日志
        logging.info(f"创建候选者:host={self.host}, port={self.port}, type={self.type}")

    @classmethod
    def get_fixed_port(cls) -> int:
        """
        返回固定端口值,并记录日志。
        """
        fixed_port = cls.FIXED_PORT
        logging.debug(f"Returning fixed port: {fixed_port}")
        return fixed_port

    @classmethod
    def from_sdp(cls, sdp: str):
        """
        从 SDP 字符串中解析一个 ICE 候选者。

        示例 SDP:
        '6815297761 1 udp 659136 192.168.1.1 12345 typ host'
        """
        bits = sdp.split()
        if len(bits) < 8:
            raise ValueError("SDP 描述字段不足")

        kwargs = {
            "foundation": bits[0],
            "component": int(bits[1]),
            "transport": bits[2],
            "priority": int(bits[3]),
            "host": bits[4],
            "port": cls.get_fixed_port(),  # 使用固定端口
            "type": bits[7],
        }

        # 提取 SDP 中的附加信息
        for i in range(8, len(bits), 2):
            if bits[i] == "raddr":
                kwargs["related_address"] = bits[i + 1]
            elif bits[i] == "rport":
                kwargs["related_port"] = int(bits[i + 1])
            elif bits[i] == "tcptype":
                kwargs["tcptype"] = bits[i + 1]
            elif bits[i] == "generation":
                kwargs["generation"] = int(bits[i + 1])

        return cls(**kwargs)

    def to_sdp(self) -> str:
        """
        返回一个适用于 SDP 的字符串表示形式。
        """
        sdp = f"{self.foundation} {self.component} {self.transport} {self.priority} {self.host} {self.port} typ {self.type}"
        if self.related_address is not None:
            sdp += f" raddr {self.related_address}"
        if self.related_port is not None:
            sdp += f" rport {self.related_port}"
        if self.tcptype is not None:
            sdp += f" tcptype {self.tcptype}"
        if self.generation is not None:
            sdp += f" generation {self.generation}"
        return sdp

    def can_pair_with(self, other) -> bool:
        """
        判断本地候选者是否可以与远程候选者配对。

        配对条件:
        - 组件相同
        - 使用相同的传输协议
        - IP 地址版本相同
        """
        a = ipaddress.ip_address(self.host)
        b = ipaddress.ip_address(other.host)
        return (
            self.component == other.component
            and self.transport.lower() == other.transport.lower()
            and a.version == b.version
        )

    def __repr__(self) -> str:
        """
        返回候选者的字符串表示形式。
        """
        return f"Candidate({self.to_sdp()})"


# 工具函数部分
def candidate_foundation(candidate_type: str, candidate_transport: str, base_address: str) -> str:
    """
    计算候选者的 Foundation(基础标识符)。
    """
    key = f"{candidate_type}|{candidate_transport}|{base_address}"
    return hashlib.md5(key.encode("ascii")).hexdigest()


def candidate_priority(candidate_component: int, candidate_type: str, local_pref: int = 65535) -> int:
    """
    计算候选者优先级。
    优先级从高到低的顺序为:host > srflx > relay。
    """
    type_preferences = {
        "host": 126,   # Host 类型优先级最高
        "srflx": 100,  # Server reflexive 类型
        "relay": 0,    # Relay 类型优先级最低
    }
    type_pref = type_preferences.get(candidate_type, 0)
    return (1 << 24) * type_pref + (1 << 8) * local_pref + (256 - candidate_component)


# 测试代码部分
if __name__ == "__main__":
    # 测试创建候选者
    candidate = Candidate(
        foundation="1",
        component=1,
        transport="udp",
        priority=candidate_priority(1, "host"),
        host="192.168.168.77",  # 使用你的本地 IP 地址
        type="host",
    )
    print(candidate)  # 打印候选者信息
    print(candidate.to_sdp())  # 打印 SDP 字符串

    # 测试从 SDP 创建候选者
    sdp_example = "1 1 udp 100 192.168.1.1 12345 typ host"
    candidate_from_sdp = Candidate.from_sdp(sdp_example)
    print(candidate_from_sdp)  # 打印解析后的候选者
    print(candidate_from_sdp.to_sdp())  # 打印 SDP 字符串

    # 模拟 WebRTC 应用程序创建多个候选者
    candidates = [
        Candidate(
            foundation=str(i),
            component=1,
            transport="udp",
            priority=candidate_priority(1, "host"),
            host=f"192.168.1.{i % 255}",  # 使用不同的 IP 地址模拟不同设备
            type="host",
        )
        for i in range(1, 6)
    ]
    for c in candidates:
        print(c)

运行没有成功

在这里插入图片描述

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

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

相关文章

Java(二十五)final关键字

Java中的final关键字在编写程序中,比较常用。尤其是在上文中的匿名内部类中。 final 表示最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思。 使用final修饰的的类,是“断子绝孙”的。 一:final修饰成员变量 Final修饰的类的成员变量是常量,不可被改变。 …

MySQL三大日志-Redo Log

Redo Log简介 事务中修改的任何数据&#xff0c;将最新的数据备份存储的位置&#xff08;Redo Log&#xff09;&#xff0c;被称为重做日志。 Redo Log 的生成和释放 随着事务操作的执行&#xff0c;就会生成Redo Log&#xff0c;在事务提交时会将产生Redo Log写入Log Buff…

【libuv】Fargo信令2:【深入】client为什么收不到服务端响应的ack消息

客户端处理server的ack回复,判断链接连接建立 【Fargo】28:字节序列【libuv】Fargo信令1:client发connect消息给到server客户端启动后理解监听read消息 但是,这个代码似乎没有触发ack消息的接收: // 客户端初始化 void start_client(uv_loop_t

html中实用标签dl dt dd(有些小众的标签 但是很好用)

背景描述 html <dl> <dt> <dd>是一组合标签&#xff0c;他们与ol li、ul li标签很相似 但是他却是没有默认前缀并且有缩进的标签 使用方式与table表格的标签一致 使用方式 dt和dd是放于dl标签内&#xff0c;dt与dd处于dl下相同级。就是dt不能放入dd内&am…

Mysql索引类型总结

按照数据结构维度划分&#xff1a; BTree 索引&#xff1a;MySQL 里默认和最常用的索引类型。只有叶子节点存储 value&#xff0c;非叶子节点只有指针和 key。存储引擎 MyISAM 和 InnoDB 实现 BTree 索引都是使用 BTree&#xff0c;但二者实现方式不一样&#xff08;前面已经介…

kubeadm_k8s_v1.31高可用部署教程

kubeadm_k8s_v1.31高可用部署教程 实验环境部署拓扑图**部署署架构****Load Balance****Control plane node****Worker node****资源分配&#xff08;8台虚拟机&#xff09;**集群列表 前置准备关闭swap开启ipv4转发更多设置 1、Verify the MAC address and product_uuid are u…

M3D: 基于多模态大模型的新型3D医学影像分析框架,将3D医学图像分析从“看图片“提升到“理解空间“的层次,支持检索、报告生成、问答、定位和分割等8类任务

M3D: 基于多模态大模型的新型3D医学影像分析框架&#xff0c;将3D医学图像分析从“看图片“提升到“理解空间“的层次&#xff0c;支持检索、报告生成、问答、定位和分割等8类任务 论文大纲理解1. 确认目标2. 分析过程&#xff08;目标-手段分析&#xff09;核心问题拆解 3. 实…

Word图片嵌入格式不正确的解决办法

问题描述: 如图, 粘贴到word的图片只显示底部一部分 解决方法: 第一步 先将图片嵌入文本行中 第二步 再将图片设置为正文格式 然后就出来了

深入浅出:内网黄金票据与白银票据

在域环境中&#xff0c;Kerberos认证是确保安全通信的基石&#xff0c;而黄金票据和白银票据则是攻击者常用的两种经典手段。为了帮助大家更形象地理解它们的工作原理及防御措施&#xff0c;我们不妨将其与在私人电影院购票的情景做类比。具体内容参考如下图示即可&#xff1a;…

Eclipse2024无法创建Dynamic Web project解决方法

Dynamic Web Project 是由 Eclipse Web Developer Tools 提供的&#xff0c;确保你已经安装了该插件。 在 Eclipse 中&#xff0c;点击菜单栏的 Help > Eclipse Marketplace&#xff0c;搜索 Eclipse Web Developer Tools&#xff0c;然后安装或更新它。 等待安装完成重启一…

Unity复刻胡闹厨房复盘 模块一 新输入系统订阅链与重绑定

本文仅作学习交流&#xff0c;不做任何商业用途 郑重感谢siki老师的汉化教程与代码猴的免费教程以及搬运烤肉的小伙伴 版本&#xff1a;Unity6 模板&#xff1a;3D 核心 渲染管线&#xff1a;URP ------------------------------…

Edge Scdn防御网站怎么样?

酷盾安全Edge Scdn&#xff0c;即边缘式高防御内容分发网络&#xff0c;主要是通过分布在不同地理位置的多个节点&#xff0c;使用户能够更快地访问网站内容。同时&#xff0c;Edge Scdn通过先进的技术手段&#xff0c;提高了网上内容传输的安全性&#xff0c;防止各种网络攻击…

开源数字人系统源码短视频文案提取文案改写去水印小程序

应用场景 短视频去水印&#xff1a; 个人用户&#xff1a;在社交媒体上分享短视频时&#xff0c;去除原视频中的水印&#xff0c;以保护个人隐私或避免侵权问题。企业用户&#xff1a;在广告、宣传和营销活动中&#xff0c;使用无水印的短视频以提高品牌知名度和吸引力。 文案提…

Everything实现,快速搜索文件

最近编写NTFS文件实时搜索工具, 类似 Everything 这样, 翻阅了很多博客, 结果大致如下: 1.分析比较肤浅, 采用USN日志枚举来获取文件记录 速度一言难尽, 因为日志枚举的是全盘所有文件的所有日志, 记录比文件记录还多, 速度当然很慢, 还有的甚至于是 使用 DeviceIoControl 函数…

Linux环境下使用tomcat+nginx部署若依项目

Linux Tomcat MySQL Java 是构建动态网站系统的完美解决方案之一&#xff0c;具有免费、高 效、扩展性强且资源消耗低等优良特性。 Java Web 凭借其优秀的开发框架和良好的生态被广 泛应用于社会各行业的信息化系统构建。 本实验以若依管理系统&#xff08; http://ruo…

.NET重点

B/S C/S什么语言 B/S&#xff1a; 浏览器端&#xff1a;JavaScript&#xff0c;HTML&#xff0c;CSS 服务器端&#xff1a;ASP&#xff08;.NET&#xff09;PHP/JSP 优势&#xff1a;维护方便&#xff0c;易于升级和扩展 劣势&#xff1a;服务器负担沉重 C/S java/.NET/…

前端HTTP协议传输以及背后的原理总结

一、HTTP在前端的地位 HTTP 是一种用作获取诸如 HTML 文档这类资源的协议。它是 Web 上进行任何数据交换的基础&#xff0c;同时&#xff0c;也是一种客户端—服务器&#xff08;client-server&#xff09;协议&#xff0c;也就是说&#xff0c;请求是由接受方——通常是…

城市应急指挥系统

城市应急指挥系统的重要性 随着现代化城市的高速发展&#xff0c;我们面临着多种应急突发情景&#xff0c;如自然灾害、事故灾难、公共卫生事件以及社会安全事件等。这些事件对城市的安全稳定构成严重威胁&#xff0c;因此&#xff0c;建立一套高效、全面的城市应急指挥系统显…

【软考高级】系统架构设计师复习笔记-精华版

文章目录 前言0 系统架构设计师0.1 考架构还是考系分0.2 架构核心知识0.3 架构教材变化 1 计算机操作系统1.1 cpu 组成1.2 内核的五大功能1.3 流水线技术1.4 段页式存储1.5 I/O 软件1.6 文件管理1.7 系统工程相关 2 嵌入式2.1 嵌入式技术2.2 板级支持包&#xff08;BSP&#xf…

NSDT 3DConvert:高效实现大模型文件在线预览与转换

NSDT 3DConvert 作为一个 WebGL 展示平台&#xff0c;能够实现多种模型格式免费在线预览&#xff0c;并支持大于1GB的OBJ、STL、GLTF、点云等模型进行在线查看与交互&#xff0c;这在3D模型展示领域是一个相当强大的功能。 平台特点 多格式支持 NSDT 3DConvert兼容多种3D模型…