2012-04-01 6 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

+5

返すと思われる 'void'関数は何ですか? – SingleNegationElimination

+0

私は強くこのようにキャストを使用しないことをお勧めします。実装しているプロトコルの仕様を確認し、そのプロトコルに従って4バイトを解釈します。キャストと最高のための希望で 'int'のものを食べるだけではありません。 –

答えて

5

definitionによってあなたはvoid機能でreturnを呼び出している明白な誤り...

recv機能を無視して、あなたのバイト数を伝える整数を読んで(または負の場合にエラー)を返します。バイトを読み込んで返したい場合は、読み取ったバイト数ではなく、coutバッファにします。

しかし、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]); 

まず、あなたは上記の例から "0 0 0 130" "130 0 0 0" かを見ていることを確認しなければなりません。今

、追加してください:

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

そして、あなたが行う場合は、130を取得するかどうかを確認し、素晴らしいです。代わりに2 181 038 080または-33 554 432を取得した場合、それはあなたのバイトの順序が間違っていることを意味します(google 'endianness')。あなたは、バイト並べ替えコマンドを使用してこの問題を解決することができます。

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

ntohl再注文をバイトエンディアンがローカルコンピュータを一致させるために。

2

コードに欠陥があります。この関数は値を返さないと宣言されていますが、それはあります。

recvは、読み取られたバイト数を返します。したがって、4が出力され、読み取られた整数はm_iVersionに格納されます。整数に130またはそれ以上の数値が含まれるかどうかは、コンピュータのエンディアンによって異なります。