Java和C++通過Socket通信中文亂碼的解決


理想的開發狀態是我開始就是C開發,一直是C的開發,現在還是C的開發,若干年后,幸運的話,我可以成為C語言的高手或者專家……

更實際的情況是我開始是C開發,后來變成了JAVA開發,然后又做起了VC++的開發,幾年下來,發現自己幾乎一無所長,成為了編程界的萬金油,這種產物很重要,但是也比較尷尬。

 

前一段時間我用C開發了一個服務器程序,前端是VC開發的客戶端。

現在我用JAVA開發了一個類似的服務器程序,前端依然是VC開發的客戶端,運行時發現,中文亂碼了。

 

先說說我的問題場景,很常見:

1 VC++客戶端請求Java服務器,Java服務器從mysql數據庫里讀取中文字符串,然后通過Socket發送給客戶端。

我以前也遇到編碼的問題,用GBK,GB2312,UTF-8一頓亂轉,竟然解決了。這次我如法炮制,各種轉,都失敗了。

再次感謝互聯網,在網上查了不少的資料,看到了不少的說法,嘗試了好多都沒有成功。

即便如此,還是有不少的啟發,沉下來自己去分析自己的代碼,最終幸運的解決了,現在梳理一下自己的思路,希望也許某一天能幫到正在抓耳撓腮的你。

 

①數據庫編碼

我的mysql數據庫的編碼是默認的latin1,打開數據庫,發現存儲的中文字符串是亂碼。這說明我存的不是latin1編碼,那是什么呢?

②數據庫插入

數據庫中的數據是通過WEB軟件插入的,查看得知插入的中文字符編碼是gb2312。

③數據庫訪問

再看一下數據庫的編碼情況,在數據庫中執行命令如下:

 1 mysql> show variables like '%char%';
 2 +--------------------------+----------------------------+
 3 | Variable_name | Value |
 4 +--------------------------+----------------------------+
 5 | character_set_client | latin1 |
 6 | character_set_connection | latin1 |
 7 | character_set_database | latin1 |
 8 | character_set_filesystem | binary |
 9 | character_set_results | latin1 |
10 | character_set_server | latin1 |
11 | character_set_system | utf8 |
12 | character_sets_dir | /usr/share/mysql/charsets/ |
13 +--------------------------+----------------------------+

我們需要重點關注的是以下幾個配置:

| character_set_client | latin1 |    客戶端的字符集

| character_set_connection | latin1 |    連接字符集

| character_set_results | latin1 |    結果字符集

可以在訪問數據庫時,通過發送語句【set names gb2312】設置需要的編碼格式。

我沒有在訪問數據庫時手動的設置編碼,所以得到的結果集應該是latin1編碼。

④編碼轉換

按照以上的步驟分析,就是現在我的Java程序得到的是latin1編碼的字符串,我需要正確的把它編碼為原始的gb2312。

感謝Java的便捷,一句話就完成了兩次編碼轉換:

1 String encodeStr = new String(mysqlResult.getBytes("iso-8859-1"),"gb2312")  //latin1編碼在Java中的編碼標識為"iso-8859-1"。

此時在程序中經過打印論證了編碼的正確性,能夠得到WEB頁面實際輸入的中文字符串。

⑤Socket發送

然后我信心滿滿的將這個轉換后的結果通過BufferedWriter發送給VC++客戶端。

結果,竟然還是亂碼!!!

這是為什么呢???

再次的查找資料,得到了結論:

Java通過Socket發送的字符流默認編碼格式為utf-8,而VC++的Socket默認的字符接收編碼方式為gb2312。

只需要修改Java端的Socket發送編碼即可:

1 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream(),"gb2312"));

OK,至此,我的VC++客戶端能夠正確的顯示中文字符了。

如果其中我理解的原理有偏差,還望各位朋友不吝賜教。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM