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

相关推荐
闲人编程1 天前
WebSocket实时通信协议深度解析
网络·websocket·网络协议·安全·通信·codecapsule
无名3872 天前
测试 Securing Kamailio’s JSON-RPC over HTTP
通信
闲人编程3 天前
Django微服务架构:单体应用拆分解耦实践
微服务·架构·消息队列·django·api·通信·codecapsule
xixixi777775 天前
解析一下传输安全——“它是什么”,更是关于“它为何存在”、“如何实现”以及“面临何种挑战与未来”
网络·安全·通信
xixixi777775 天前
解析一下存储安全——“它是什么”,更是关于“它为何存在”、“如何实现”以及“面临何种挑战与未来”
网络·安全·通信
xixixi777778 天前
3GPP核心网的演进:是一条清晰的去电信化和IT化道路
网络·协议·通信·3gpp
xixixi7777715 天前
通信电子围栏——对特定终端(手机/物联网卡)进行实时监控和预警
安全·监控·通信·电子围栏·电子边界
无名38724 天前
记录 RTPEngine Dockerfile 的调试过程
通信
无名3871 个月前
OpenSIPS sql_cacher vs sqlops
通信