2017-05-09 86 views
2

从C++客户端我发送一个6字节的缓冲区到C#服务器。如何正确地将C++ ulong 4字节的IP地址转换为C#类型?

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时,我得到一个例外。

我不明白为什么它只是偶尔发生,我做错了什么?

+0

为什么在IP地址上使用'htonl'和'NetworkToHostOrder'(我知道这是可移植的方式,如果你想支持小型和大型端节点)而不是端口? – Jonas

+0

当IPv4地址恰好是32位时,为什么'addressx'定义为'long'(64位?)? – Jonas

+0

@Jonas我试着把它定义为int,问题是一样的:/我写道端口已经被颠倒了。 –

回答

1

这里的问题是您的addressx或者小于零或者大于0x00000000FFFFFFFF。

发生这种情况是因为您在拨打IPAddress.NetworkToHostOrder(address);addressuint。由于没有超出NetworkToHostOrder()接受uint,这是促进参数long和调用NetworkToHostOrder(long)。这对于一些投入产生了负值。

你需要做的是调用,通过使用int形式的地址接收一个int版本:

int address = BitConverter.ToInt32(temp, 0); 

现在当你调用NetworkToHostOrder()你会得到一个(可能为负)int回来,你需要转换到uint

uint addressx = (uint) IPAddress.NetworkToHostOrder(address); 

现在,这应该工作:

destAddress = (new IPAddress(addressx).ToString()); 
+0

我发现你发布它的那一刻已经算出来了!感谢您的回答和解释,现在更有意义:) –

相关问题