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

相关推荐
SunkingYang5 小时前
QT程序如何将事件和消息发送给MFC程序,MFC程序如何接收消息和事件
qt·mfc·消息·事件·通信·通讯·传递
灵感菇_9 小时前
Android ContentProvider全面解析
android·通信·四大组件·contentprovider
无名3872 天前
rtpengine-recording(8) 手册页
通信
无名3875 天前
FreeSWITCH limit 中文手册
通信
xixixi777776 天前
系统性地解析——边缘计算(从定义与驱动力、核心架构、关键技术特征、与云计算的范式对比、典型应用场景以及挑战与趋势等方面)
安全·架构·云计算·边缘计算·信息与通信·通信·反诈
xixixi777779 天前
从宏观架构、核心技术、战术对抗、治理挑战和未来趋势五个层面,系统性地剖析“短信反诈骗”
安全·架构·安全架构·通信·反诈·短信反诈
无名38710 天前
Kamailio usrloc 细节测试
通信
xixixi7777710 天前
App反诈骗:一场面向移动生态的深度安全战争(接上文短信反诈)
安全·信息与通信·通信·电话反诈
无名38714 天前
FusionPBX Debian 12 安装
运维·debian·通信
交换机路由器测试之路16 天前
什么是网络直径
网络·以太网·交换机·通信