1. 程式人生 > >JAVA與C++用socket通訊出現中文亂碼

JAVA與C++用socket通訊出現中文亂碼

java接收C++資料出現中文亂碼:

將java這邊的socket編碼改為GBK就行了!

java和C++使用Socket通訊,其實底層Socket都是相通的,所以只需要按照各自的語法去做就是了。

java伺服器端使用ServerSocket的accept建立Socket,跟普通java之間的通訊一致。

C++客戶端使用makeConnect(server, port, "tcp"),send,recv等函式。

自己在這次程式設計中,首先遇到的是雖然連線成功了,但java無法接收C++發來的訊息。

可能是用錯函式之類的,後邊改為下邊的程式碼接收就沒事了。

複製程式碼 1 1//接受資料,但不允許有中文,因為會亂碼
2 2 DataInputStream in =new DataInputStream(clientSocket.getInputStream()); 3 3byte[] buffer =newbyte[10000]; //緩衝區的大小4 4 in.read(buffer); //處理接收到的報文,轉換成字串5 5/**6 6 * C++傳遞過來的中文字,需要轉化一下。C++預設使用GBK。 7 7 * GB2312是GBK的子集,只有簡體中文。因為資料庫用GB2312,所以這裡直接轉為GB2312
8 8 * */9 9 message =new String(buffer,"GB2312").trim(); 複製程式碼

另外

最大的問題是字元的編碼問題,如果發現java接收到的字串是亂碼,就要仔細看看接下來的說明了。

而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。  

複製程式碼 1 //獲得輸出輸出流2 out = newPrintStream(clientSocket.getOutputStream()); 3 out.print(test);//直接UTF8輸出,最終底層每個中文用3個位元組傳輸4 out.print(newString(test.getBytes(),"GBK"));//轉GBK失敗,實際每個中文字用了4到5個位元組傳遞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定義了一個異常。