2017-05-09 88 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

我發現你發佈它的那一刻已經算出來了!感謝您的回答和解釋,現在更有意義:) –

相關問題