1. 准备工作
1) 服务器设置
服务器需要2个公网IP(主地址,从地址),绑定3个端口(直接回复、换IP回复、换Port回复)。
2) 客户端设置
客户端要主动接收数据,也需要绑定一个端口。
3) 通信数据包
// 请求数据
struct sReqData
{
sReqData()
{
memset(this, 0, sizeof(sReqData));
}
unsigned short usType;
unsigned long ulStamp;
};
// 回复数据
struct sRspData
{
sRspData()
{
memset(this, 0, sizeof(sRspData));
}
unsigned short usType;
unsigned long ulStamp;
unsigned long ulCIp;
unsigned short usCPort;
};
说明:
usType: 标识请求类型。包括:主地址直接回复、主地址换IP回复、主地址换端口回复、从地址直接回复。ulStamp: 标识请求和回复是否匹配。
ulCIp: 服务器看到的客户端的公网IP。
usCPort: 服务器看到的客户端的公网Port。
2. 通信流程
参照上一篇中“NAT的检测步骤”,简化通信流程如下:
第一步、请求主地址直接回复客户端的IP1和Port1。
如未收到回复,表明本地不能进行UDP通信。可能是防火墙阻止了(测试停止)。
如能收到回复,表明本地能够进行UDP通信。记下公网地址(IP1,Port1),并将公网地址与本地地址进行比较。如果一致,为公网(测试停止);否则,进行后续测试。
第二步、请求主地址换IP回复。
如能收到回复,表明本地为全锥形NAT(测试停止)。
如未收到回复,进行后续测试。
第三步、请求从地址直接回复客户端的IP2和Port2。
如(IP2、Port2)与(IP1、Port1)不同,表明本地为对称NAT(测试停止)。
如(IP2、Port2)与(IP1、Port1)相同,进行后续测试。
第四步、请求主地址换Port回复。
如未收到回复,表明本地为端口限制NAT。
如能收到回复,表明本地为限制NAT。