2012-04-01 199 views
3

下面的代碼從一個套接字讀取4個字節到一個整數。我可以看到字節是(十進制)130 0 0 0.我懷疑下面的代碼將返回版本130,但我不知道爲什麼。這會返回130嗎?我試圖在Java中複製它,但我是一個非常大的負數(更多我期望的)。我如何解釋下面的僞/ C代碼?將4個字節的字節轉換爲一個int

#include <socket.h> 
void readVersion(char *buf, int iCount) { 
     recv(hSocket, buf, iCount, MSG_WAITALL); 
} 
int m_iVersion; 
readVersion((char *) &m_iVersion, sizeof (m_iVersion)) 
count << m_iVersion; 
+5

我認爲你真正的問題是關於_ [endianness](http://en.wikipedia.org/wiki/Endianness)_。 – ildjarn 2012-04-01 18:13:13

+5

什麼是應該返回的「void」函數? – SingleNegationElimination 2012-04-01 18:13:47

+0

我強烈建議不要使用這種方式施放。檢查你正在執行的協議的規範,並根據該協議解釋四個字節。不要只是在演員陣容中充當一個'int',並希望最好。 – 2012-04-01 19:14:51

回答

5

忽略您在void函數調用return明顯的錯誤...

recv功能,通過definition,返回一個整數告訴你的字節數讀取(或負如果誤差)。如果你想讀取字節並返回它們,你想要緩衝區,而不是讀取的字節數。

但是,打印一個int將打印整個事情..不是像你所期望的逐字節。那樣的事情呢?

int nb, i; 
union { 
    uint32_t whole; 
    char bytes[4]; 
} v; 
nb = recv(hSocket, v.bytes, 4, MSG_WAITALL); 
if (nb != 4) 
    printf("Error: recv returned: %d\n", nb); 
else 
    printf("%d %d %d %d\n", v.bytes[0], v.bytes[1], v.bytes[2], v.bytes[3]); 

首先,你應該確保你從上面的例子中看到 「130 0 0 0」 或 「0 0 0 130」。

現在,試着加入:

printf("%u\n", v.whole); 

,看看你得到130如果你這樣做,太好了。如果你得到2 181 038 080-33 554 432這意味着你的字節順序錯誤(谷歌'排序')。你可以用一個字節重新排序命令解決這個問題:

v.whole = ntohl(v.whole); 
printf("%u\n", v.whole); 

ntohl重新排序的字節,使字節順序匹配您的本地計算機。

2

代碼有缺陷。該函數被聲明爲不返回值,但它確實。

recv返回讀取的字節數,所以它會打印4,整數讀取將存儲在m_iVersion。整數是130還是大數取決於計算機的字節順序。