我正在尝试解析用户输入的IP地址信息的方法,例如:
192.168.100.10
192.168.100.10:80
21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2
21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A
[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2]:8080
21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080
www.microsoft.com
www.microsoft.com:80
WinAPI函数ParseNetworkString声称能够解析所有这些格式(列表来自文档)。其中许多确实可以解析。但是有些失败:
192.168.100.10
✅192.168.100.10:80
✅21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2
✅21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A
✅[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2]:8080
❌21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080
❌www.microsoft.com
✅www.microsoft.com:80
✅所以是伪代码:
NET_ADDRESS_INFO^ addressInfo;
UInt16^ portNumber;
UInt8^ prefixLength;
DWORD res = ParseNetworkString(
"21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080", //NetworkString
NET_STRING_IPV6_SERVICE_NO_SCOPE, //Types
addressInfo, portNumber, lengthPrefix);
返回87 The Parameter is incorrect.。
我在做什么错?
以API表示可以解析的相同方式:
192.168.100.10:8080
\____________/ \__/
| |
Address Port
它还声称它可以解析:
21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080
\_____________________________________/ \__/
| |
Address Port
某些人可能会反对,并声称在规范的IPv6地址中包含端口号的唯一方法是将地址部分括在[方形backets]中。那些人根本是错的。 Source: RFC5952
最后,我们想要的是能够将用户输入的内容传递给WSAConnectByName,这需要:
nodeName
:例如“ 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A”serviceName
例如“ 3119”该文档完全不正确。如果您拆解ParseNetworkString()
,您会发现它调用RtlIpv6StringToAddressEx()
,即documented,如[emphasis添加):
AddressString参数指向的字符串必须以IPv6地址字符串的形式表示,后跟可选的百分比字符和作用域ID字符串。 IPv6地址和作用域ID字符串必须放在方括号中。 IPv6地址和作用域ID字符串后的右方括号后面可以是可选的冒号和端口号的字符串表示形式。