1. 程式人生 > >C/C++與java網路通訊問題彙總及解決方法

C/C++與java網路通訊問題彙總及解決方法

前段時間做了一個簡單的C/S系統, 分別用C++和java開發服務端和客戶端, 並通過tcp通訊. 以前沒有這方面的經驗, 只是知道理論上可行, 實際上還有不少問題要注意.
本文會陸續擴充和修改.

專案1: 校園導航 2006.6
平臺: X86, windowsXP+SP2, mingw3.4.5, jdk1.5.0_06
C++:socket, send, recv
java: Socket, DataInputStream, DataOutputStream
1. 位元組序, C++在不同的平臺上有不同的位元組序, X86上是little-endian, solaris上是big-endian; 而java在所有平臺上都預設是big-endian, 所以在傳輸諸如short,int,long資料時要在C++轉換成網路序(big-endian)

2. 字元編碼, C++上最普遍的是採用mbcs, 而java上是用unicode(並且和標準的unicode還有些區別,可以參考java文件), 所以除非必須否則不要傳字串, 可以傳文字檔案代替, 一定要傳的話只能自己轉換了

3. 記憶體對齊, 在C/C++的網路通訊程式中經常採用讀寫結構體的方式方便地交換資料, 但是不注意的話結構體內很可能有空隙, 比如struct A{ int a; char c }; struct B{ char a; int b }; 這兩個結構體內都有空隙, 而如果不說明空隙的存在java程式是不會知道的, 就會導致雙方解析時出錯. 要消除空隙應該小心地安排結構體的成員, 不推薦使用#pragma pach(1), 因為沒有通用性

4. 位域, 除非小心安排, 否則位域導致的結構體大小與平臺相關, int a:4所佔用的位元組隨平臺和編譯器變化(char a:4相對穩定佔1位元組)

4. (可能平臺相關)傳送與接收速度不同, 當C++向java傳送一個大一些的資料時, 可能C++一邊已經傳完退出了, 而java那邊還沒收完, 導致最後的一部分資料丟失. 所以專案中採用了簡單的確認機制, 任何一方接收完資料就回送1位元組的確認, 以防止C++過早退出

5. (可能平臺相關)java在同C++建立連線後以及在C++向java傳送完一段資料後, java若向C++傳送一段資料則第一次傳送的資料C++只能收到一個位元組, 第一次過後恢復正常