原文鏈接: http://www.cnblogs.com/kenkofox/archive/2010/04/25/1719649.html
代碼:
http://files.cnblogs.com/kenkofox/Client-CPlusPlus.rar
http://files.cnblogs.com/kenkofox/Server_Java.rar
java和C++使用Socket通信,其實底層Socket都是相通的,所以只需要按照各自的語法去做就是了。
java服務器端使用ServerSocket的accept創建Socket,跟普通java之間的通信一致。
C++客戶端使用makeConnect(server, port, "tcp"),send,recv等函數。
自己在這次編程中,首先遇到的是雖然連接成功了,但java無法接收C++發來的消息。
可能是用錯函數之類的,后邊改為下邊的代碼接收就沒事了。
1 //接受數據,但不允許有中文,因為會亂碼 2 DataInputStream in = new DataInputStream(clientSocket.getInputStream()); 3 byte[] buffer = new byte[10000]; //緩沖區的大小 4 in.read(buffer); //處理接收到的報文,轉換成字符串 5 /** 6 * C++傳遞過來的中文字,需要轉化一下。C++默認使用GBK。 7 * GB2312是GBK的子集,只有簡體中文。因為數據庫用GB2312,所以這里直接轉為GB2312 8 * */ 9 message = new String(buffer,"GB2312").trim();
另外
最大的問題是字符的編碼問題,如果發現java接收到的字符串是亂碼,就要仔細看看接下來的說明了。
Java代碼在運行時,默認用UTF8來處理字符串,Socket發送字符串(如果用高層輸出流直接輸出String的話,最后還是自動用UTF8方式把字符串拆分成byte數組再傳輸的。(可以見http://www.cnblogs.com/kenkofox/archive/2010/04/23/1719009.html)
而C++在xp運行的時候默認使用GBK來傳輸Socket。
所以java接收到C++消息的時候,應該轉為GBK或者GB2312,才能顯示正確中文。
而C++要接收到正確的java消息,就要在java發送的時候轉為GBK或者GB2312編碼(因為C++轉碼比java麻煩很多嘛,哈哈)
1 byte[] responseBuffer = newClientRequestHandler(message).response().getBytes("GB2312"); 2 out.write(responseBuffer, 0,responseBuffer.length);
而C++接收方面,只需要用buf裝起來,然后轉為string就是了。正確顯示……代碼大概是:
charCount = recv(socket, buf, len, 0);
string resultString(buf);
另外為了更好理解上述的編碼問題,大家在java端發送信息到C++端的時候,試試下邊的方式試試,很有意思的。記得要在C++那邊關注charCount。
//獲得輸出輸出流 out = newPrintStream(clientSocket.getOutputStream()); out.print(test);//直接UTF8輸出,最終底層每個中文用3個字節傳輸 out.print(newString(test.getBytes(),"GBK"));//轉GBK失敗,實際每個中文字用了4到5個字節傳遞 out.print(newString(test.getBytes("GBK"),"GBK"));//轉GBK,但底層還是要拆成字節數組,當然最終還是跟UTF8一樣
接下來是完整的代碼說明
java方面:
EchoServerThread是一個Server類,專門等待客戶的連接,然后建立EchoThread進行處理。
EchoThread是一個處理消息的線程,主要包括接收消息和發送消息的socket操作。
ClientRequestHandler是處理字符串的實際業務邏輯類……
C++方面:
client.cpp是測試的主函數。
SocketManager.h包含SocketManager類,簡單封裝了Socket的啟動和發送等操作。
connection.h包含Connection類,封裝了Socket的底層調用。
conn_exception.h定義了一個異常。
