C服務端與java客戶端的socket通訊注意事項
今天這個專案需要c服務端與java客戶端進行socket通訊。
中間遇到了很多問題。
首先搜尋了一下
http://blog.sina.com.cn/s/blog_55934df80100i55l.html
有以下幾點要注意的地方:
我的客戶端是用c寫的,屬於小端模式,而TCP和java都是大端模式。所以伺服器端在傳送int WORD 或者是double等資料型別的時候必須先將小端轉換成大端模式,而在接受到資料以後必須將這些型別再重新轉換成小端模式。具體轉換可以看下面這個列表。
¨ #define ntohs(n) //16位資料型別網路位元組順序到主機位元組順序的轉換
¨ #define htons(n) //16位資料型別主機位元組順序到網路位元組順序的轉換
¨ #define ntohl(n) //32位資料型別網路位元組順序到主機位元組順序的轉換
¨ #define htonl(n) //32位資料型別主機位元組順序到網路位元組順序的轉換
typedef struct My_Send_Chinese{
byte Type;
WORD size;
char data[4];
}Send_Chinese;
我遇到的問題是這樣的。當我在傳送資料的時候,我定義了成員Type = 0x 41通過抓包工具發現Type傳送過去的資料是0x 41 cc
導致java端接收的時候出錯。那麼這裡為什麼會出現一個多出來的cc 呢?
這是結構體對齊所導致的。具體大家可以看上面那個連結。
先讓我們看四個重要的基本概念:
1.資料型別自身的對齊值:對於char型資料,其自身對齊值為1,對於short型為2,對於int,float,double型別,其自身對齊值為4,單位位元組。
2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。
3.指定對齊值:#pragma pack (value)時的指定對齊值value。
4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。
解決的辦法是新增下面這句:
#pragma pack (1)
理由就是上面的4條重要規則。