【发布时间】:2017-05-09 09:06:11
【问题描述】:
我从 C++ 客户端向 C# 服务器发送 6 个字节的缓冲区。
ULONG addr = htonl(server->sin_addr.s_addr);
USHORT port = server->sin_port; -> Already reversed to network bytes.
char frame[sizeof(USHORT) + sizeof(ULONG)];
memcpy(frame, &port, sizeof(USHORT));
memcpy(&frame[2], &addr, sizeof(ULONG));
int result = send(s, (const char*)frame, sizeof(frame), 0);
如你所见,缓冲区包含:[2字节端口,4字节地址]
在 C# 服务器端,我将端口和地址从网络转换为主机字节。我已经检查以确保接收到的缓冲区始终为 6 个字节。
ushort port = BitConverter.ToUInt16(buffer, 0);
byte[] temp = new byte[4];
Array.Copy(buffer, 2, temp, 0, temp.Length);
uint address = BitConverter.ToUInt32(temp, 0);
long addressx = IPAddress.NetworkToHostOrder(address);
destPort = (ushort)IPAddress.NetworkToHostOrder((short)port);
destAddress = (new IPAddress(addressx).ToString());
有时,我在初始化 new IPAddress(address) 时遇到异常,ArgumentOutOfRangeException。
我不明白为什么它只是有时会发生,我做错了什么?
【问题讨论】:
-
为什么你在 IP 地址上使用
htonl和NetworkToHostOrder(我知道如果你想同时支持小端和大端节点,这是可移植的方式)而不是端口? -
当 IPv4 地址正好是 32 位时,为什么
addressx被定义为long(64 位?)? -
@Jonas 我尝试将它定义为 int 并且问题是一样的:/我写道端口已经反转了。
-
一个 Uint32 只有 4 个字节,而你想要 6 个字节。
-
你帮的太多了。请改用 IPAddress(byte[]) 构造函数,字节顺序已被假定为网络顺序,并且 byte[] 的大小可确保您始终获得 IPv4 地址。
标签: c# c++ networking