用 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 确实强

相关推荐
无名38713 小时前
RTPProxy 2.2 用户手册
通信
xixixi777771 天前
今日 AI 、通信、安全前沿日报(2026 年 2 月 5 日,星期四)
人工智能·网络安全·ai·信息安全·大模型·通信·前沿
无名3871 天前
高吞吐与性能优化:Kamailio调优指南
通信
xixixi777772 天前
今日 AI 、通信、安全行业前沿日报(2026 年 2 月 4 日,星期三)
大数据·人工智能·安全·ai·大模型·通信·卫星通信
无名3873 天前
测试 kamailio v6.0.5 的 nats 模块(预处理)
通信
Trouvaille ~3 天前
【Linux】网络编程基础(二):数据封装与网络传输流程
linux·运维·服务器·网络·c++·tcp/ip·通信
百锦再3 天前
《C#上位机开发从门外到门内》2-7:网络通信(TCP/IP、UDP)
tcp/ip·udp·c#·嵌入式·上位机·通信·下位机
一路向北⁢4 天前
Spring Boot 3 整合 SSE (Server-Sent Events) 企业级最佳实践(一)
java·spring boot·后端·sse·通信
一路向北⁢4 天前
Spring Boot 3 整合 SSE (Server-Sent Events) 企业级最佳实践(二)
java·数据库·spring boot·sse·通信
【 STM32开发 】4 天前
【STM32 + CubeMX】 CAN 通信
stm32·cubemx·can·hal·通信·f407