用 Gemini 2.5 Pro 产生 RTPEngine perl 测试程序

提示为:

用 perl 写 rtpengine 测试程序,尽量简单,支持 ping/offer/answer/delete

Gemini 2.5 Pro 产生的代码如下:

perl 复制代码
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
use Convert::Bencode qw(bencode bdecode);
use Data::Dumper;

# ================= 配置区域 =================
my $RTPENGINE_HOST = '127.0.0.1'; # rtpengine 地址
my $RTPENGINE_PORT = 2223;        # rtpengine ng 监听端口
my $TIMEOUT        = 2;           # 超时时间 (秒)
# ===========================================

# 创建 UDP Socket
my $socket = IO::Socket::INET->new(
    Proto    => 'udp',
    PeerAddr => $RTPENGINE_HOST,
    PeerPort => $RTPENGINE_PORT
) or die "无法连接到 $RTPENGINE_HOST:$RTPENGINE_PORT : $!\n";

print "连接到 rtpengine ($RTPENGINE_HOST:$RTPENGINE_PORT)...\n\n";

# 生成一个用于测试的 Call-ID
my $test_call_id = "perl-bencode-test-" . int(rand(99999)) . "@" . $RTPENGINE_HOST;
my $from_tag     = "tag-" . int(rand(99999));
my $to_tag       = "tag-" . int(rand(99999));

# 模拟 SDP (用于 Offer)
my $sdp_offer = <<'END';
v=0
o=- 123456 123456 IN IP4 1.1.1.1
s=-
c=IN IP4 1.1.1.1
t=0 0
m=audio 10000 RTP/AVP 0
a=rtpmap:0 PCMU/8000
END

# 模拟 SDP (用于 Answer)
my $sdp_answer = <<'END';
v=0
o=- 654321 654321 IN IP4 2.2.2.2
s=-
c=IN IP4 2.2.2.2
t=0 0
m=audio 20000 RTP/AVP 0
a=rtpmap:0 PCMU/8000
END

# ================= 执行测试流程 =================

# 1. 测试 Ping
print "=== [1] 测试 PING ===\n";
send_request("ping", {});

# 2. 测试 Offer
print "\n=== [2] 测试 OFFER ===\n";
my $offer_params = {
    'call-id' => $test_call_id,
    'from-tag' => $from_tag,
    'sdp' => $sdp_offer,
    'replace' => ['origin', 'session-connection'], # 示例参数
};
send_request("offer", $offer_params);

# 3. 测试 Answer
print "\n=== [3] 测试 ANSWER ===\n";
my $answer_params = {
    'call-id' => $test_call_id,
    'from-tag' => $from_tag,
    'to-tag' => $to_tag,
    'sdp' => $sdp_answer,
    'replace' => ['origin', 'session-connection'],
};
send_request("answer", $answer_params);

# 4. 测试 Delete
print "\n=== [4] 测试 DELETE ===\n";
my $delete_params = {
    'call-id' => $test_call_id,
    'from-tag' => $from_tag,
};
send_request("delete", $delete_params);

# 关闭 Socket
$socket->close();
print "\n测试结束。\n";


# ================= 核心函数 =================

sub send_request {
    my ($command, $params_href) = @_;

    # 1. 将命令本身也放入参数哈希中
    $params_href->{command} = $command;

    # 2. 生成 Cookie (用于匹配响应)
    my $cookie = int(rand(1000000)) . "_cookie";

    # 3. 编码数据为 bencode 格式
    my $bencoded_data = bencode($params_href);

    # 4. 构造 ng 协议数据包: "Cookie BencodedData"
    my $packet = "$cookie $bencoded_data";

    # 5. 发送
    $socket->send($packet) or die "发送失败: $!\n";
    
    # 6. 接收响应 (带超时处理)
    my $response_data;
    eval {
        local $SIG{ALRM} = sub { die "timeout" };
        alarm $TIMEOUT;
        $socket->recv($response_data, 65535); # 最大 UDP 包大小
        alarm 0;
    };

    if ($@) {
        if ($@ =~ /timeout/) {
            print "错误: 接收超时 (rtpengine 未运行或端口错误?)\n";
        } else {
            print "错误: $@\n";
        }
        return;
    }

    # 7. 解析响应
    # 响应格式: "Cookie BencodedBody"
    my ($resp_cookie, $resp_body) = split(/\s+/, $response_data, 2);

    if ($resp_cookie ne $cookie) {
        print "警告: Cookie 不匹配! 发送: $cookie, 接收: $resp_cookie\n";
    }

    print "Command: $command\n";
    print "Status: ";
    
    if ($resp_body) {
        my $resp_decoded = eval { bdecode($resp_body) };
        if ($@) {
            print "Bencode 解析失败: $@\n";
        } else {
            if ($resp_decoded->{result} && ($resp_decoded->{result} eq 'ok' || $resp_decoded->{result} eq 'pong')) {
                print "OK\n";
                if ($resp_decoded->{sdp}) {
                    print "  - Rtpengine 返回了新的 SDP\n";
                }
            } else {
                print "ERROR\n";
                # 使用 Data::Dumper 打印详细的错误信息
                print Dumper($resp_decoded);
            }
        }
    } else {
        print "Empty response\n";
    }
}

cpan Convert::Bencode

perl test.pl

输出如下:

连接到 rtpengine (127.0.0.1:2223)...

=== 1 测试 PING ===

Command: ping

Status: OK

=== 2 测试 OFFER ===

Command: offer

Status: OK

  • Rtpengine 返回了新的 SDP

=== 3 测试 ANSWER ===

Command: answer

Status: OK

  • Rtpengine 返回了新的 SDP

=== 4 测试 DELETE ===

Command: delete

Status: OK

测试结束。


现在的 AI 确实强

相关推荐
搞科研的小刘选手5 分钟前
【广州大学主办 | IEEE出版 | 落地广州】第八届国际科技创新学术交流大会暨通信、信息系统和软件工程学术会议(CISSE 2026)
软件工程·通信·信息系统·学术会议·广州大学·科技创新·会议推荐
so~what7 天前
6G Day 1
信息与通信·通信
littleBird_211 天前
NR 5G-A NTN 小区搜索及NTN相关SIB
5g·通信·nr
搞科研的小刘选手11 天前
【见刊检索快 | 重庆线上线下同步】第五届信号处理、计算机网络与通信国际学术会议(SPCNC 2026)
计算机网络·信号处理·通信·学术会议·会议推荐·重庆
星恒讯工业路由器14 天前
双栈时代的访问断层:当同一个域名走向两条网络路径
网络·物联网·信息与通信·ipv4·通信·ipv6·双栈网络
littleBird_215 天前
NR 5G-A NTN技术概述
5g·通信·nr
一条大祥脚22 天前
26CCPC网络赛 DFS|数学|解方程|异或哈希|通信|二分|倍增|期望DP|最短路计数
通信·倍增·ccpc网络赛·疑惑哈希·期望dp
小贺儿开发24 天前
Unity 局域网遥控幻灯片展示工具 3.0
科技·http·unity·工具·ppt·通信·网页
搞科研的小刘选手1 个月前
【中国·海口(线上+线下)】2026年智能感知、通信与海洋应用国际学术会议(ISCMA 2026)
通信·学术会议·会议推荐·智能感知·海洋应用·海口·海南大学
码上有光1 个月前
Linux进程通信——共享内存、消息队列和信号量
android·linux·运维·共享内存·通信