2010-03-25 49 views
2

我正在與套接字編程打架,我遇到了一個問題,我不知道如何以便攜方式解決問題。 這個任務很簡單:我需要通過網絡發送16字節的數組,然後在客戶端應用程序中接收並解析它。我知道,有像htonl,htons和uint16和uint32這樣的函數。但是,我應該如何處理比這更大的數據塊呢?通過套接字發送任意長度的數組。 Endianness

謝謝。

回答

3

你說一個16字節的數組。這並沒有什麼幫助。字節順序只對大於一個字節的事物很重要。

如果這是真的原始字節然後只是給他們,你會收到他們一樣的

如果這是真的,你要

struct msg 
{ 
    int foo; 
    int bar; 
..... 

發送它,那麼你需要通過緩衝工作一個struct拉取你想要的值。

當您發送您必須組建一個包成一個標準的順序

int off = 0; 
*(int*)&buff[off] = htonl(foo); 
off += sizeof(int); 
*(int*)&buff[off] = htonl(bar); 
... 

當您收到

int foo = ntohl((int)buff[off]); 
off += sizeof(int); 
int bar = ntohl((int)buff[off]); 
.... 

編輯:我看你要發送的IPv6地址,他們總是處於網絡字節順序 - 所以你可以直接對它進行流式處理。

1

htonshtonl等用於處理大於一個字節的單個數據項(例如int)。其中每個字節用作單個數據項本身的字節數組(例如,字符串)根本不需要在主機和網絡字節順序之間進行轉換。

+0

我有點困惑。我的機器有little-endian字節順序,我試圖通過網絡發送ipv6地址作爲一個字節數組。據我所知,我們必須恢復字節(第16個成爲第一個),傳輸它們,並在客戶端(如果它也是小端)恢復字節。我對嗎? – 2010-03-25 20:47:21

+0

IPv6地址應該按照big-endian順序作爲數組發送。您應該(通常情況下)能夠將其視爲基本上不透明的數據 - 例如,您將收到16個字節並將它們完全按照您收到的那樣複製到sockaddr_in6中。IP堆棧可能會決定在內部交換它們,但您應該從外部看到的所有內容都將按網絡順序進行交換。有一天,如果你有一臺128位的機器,並想加載一個並將其作爲一個數字操作,那麼你不得不擔心一個'ntohlll'和'htonlll'(或任何使用的名字)。 – 2010-03-25 21:34:08

3

Endianness是多字節變量(如16位和32位整數)的屬性。它與高位或低位字節先行有關。如果客戶端應用程序將數組作爲單個字節進行處理,則不必擔心字節順序,因爲字節中的位順序相同。

1

字節本身不再有字節序,因爲計算機發送的任何單字節在不同的接收計算機中都具有相同的值。現在,字節序僅與多字節數據類型(如整數)相關。

在你的具體情況下,它歸結爲知道接收器將用你的16字節做什麼。如果它將數組中的16個條目中的每一個都視爲離散的單字節值,那麼您可以發送它們而不用擔心endiannes。另一方面,如果接收方將16字節數組視爲4個32位整數,那麼您需要在發送之前通過hton()運行每個整數。

這有幫助嗎?