aardio 文档

aardio 范例: STUN 协议

import console;
import wsock.udp.stunClient;

// 创建 STUN 客户端
var stun = wsock.udp.stunClient();
stun.udp.setTimeouts(3000, 3000);

// 第一步:基础检测
console.log("=== 第一步:检测是否在 NAT 后面 ===");
var result1, err = stun.getPublicAddress();
if(!result1) {
    return console.logPause("获取失败:", err);
}

console.log("本地 IP:", result1.localIp, ":", result1.localPort);
console.log("公网 IP:", result1.ip, ":", result1.port);
console.log("STUN 服务器:", result1.server);
console.log("耗时:", result1.duration, "秒");

if(!result1.nat) {
    return console.logPause("结论:无 NAT,直接使用公网 IP");
}

console.log("检测到 NAT");
console.log("");

// 第二步:对称型 NAT 检测
console.log("=== 第二步:检测是否为对称型 NAT ===");
console.log("向不同服务器查询,观察公网端口是否变化...");

// 获取多个服务器列表
import web.rest.github;
var servers = web.rest.github.getContent("pradt2", "always-online-stun", "valid_hosts.txt");

// 向多个服务器查询
var results = [];
for serv in  string.lines(servers) {
    var resp,err = stun.getPublicAddress(serv);
    console.status(resp,serv,,,err||(resp.duration+"秒"));  

    if(resp)  table.push(results, resp);

    if(#results>2) break;
}

if(#results < 2) {
    return console.logPause("错误:成功查询的服务器不足 2 个");
}

console.log("");

// 分析结果
var natType = "未知";
var allPortsSame = true;
var firstPort = results[1].port;

console.log(firstPort,type(firstPort))

for(i = 2; #results; 1) {
    if(results[i].port != firstPort) {
        console.log(results[i].port,type(results[i].port),"不相等",results[i].port , firstPort)
        allPortsSame = false;
        break;
    }
}

if(allPortsSame) {
    natType = "锥型 NAT (Cone NAT)";
    console.log("结论:所有服务器返回相同的公网端口 (", firstPort, ")");
    console.log("      这是锥型 NAT 的特征");
    console.log("");
    console.log("说明:");
    console.log("  - 完全锥型 (Full Cone): 任何外部主机都可以发送数据到映射端口");
    console.log("  - 受限锥型 (Restricted Cone): 只有曾通信过的 IP 可以发送数据");
    console.log("  - 端口受限锥型 (Port Restricted): 只有曾通信过的 IP:Port 可以发送数据");
    console.log("  (进一步区分需要服务器支持 CHANGE-REQUEST ,多数服务器不支持)");
}
else {
    natType = "对称型 NAT (Symmetric NAT)";
    console.log("结论:不同服务器返回不同的公网端口");
    console.dump("      端口列表:");
    for(i = 1; #results; 1) {
        console.log("        服务器", i, ":", results[i].port);
    }
    console.log("");
    console.log("说明:");
    console.log("  对称型 NAT 对每个不同的目标分配不同的端口映射");
    console.log("  这种类型的 NAT 对 P2P 连接最不友好");
}

console.log("");
console.log("=== 检测结果 ===");
console.log("NAT 类型:", natType);
console.log("公网 IP:", result1.ip);
console.log("本地 IP:", result1.localIp);

console.pause();
Markdown 格式