在手機與pc之間進行socket或http通訊時,常常會出現中文亂碼問題,其主要原因在於手機端字元編碼預設為utf-8,而伺服器pc端預設為gbk或gb2312。
手機到pc的資訊編碼傳遞、接收、解碼顯示的過程為:手機端以utf-8編碼資訊(包括漢字),寫入socket輸出流。在寫入輸出流,或在socket中傳遞時,或在pc端讀取來自手機的socket流資訊時,系統把資訊編碼進行了一次轉換(經程式設計驗證應該是轉為gbk),這樣在pc端預設以gbk方式解碼顯示來自手機的資訊,出現中文亂碼也就不足為奇了。
根據以上分析,要解決pc端顯示中文亂碼的問題,必須在pc端對接受的手機端資訊進行轉碼,具體過程如下:
1、手機端:
手機端一般可保持預設操作方式即可。當然,執行下述操作也不會產生錯誤輸出:
strsend = new string(strsend.getbytes(), "utf-8");
該操作是按照(手機)當前作業系統的編碼格式獲取字串strsend的編碼位元組(陣列),再轉換為utf-8字串,進行傳遞。由於手機端預設使用utf-8編碼,所以該操作實際上是多餘的。當然,你也可以將操作中第二個引數改變,轉換其它編碼格式傳遞試一下。
2、pc端:
tempstr = new string(mstrmsg.getbytes("gbk"),"utf-8");或者:
tempstr = new string(mstrmsg.getbytes(),"utf-8");
pc端的操作就是以預設編碼方式(這裡為gbk)獲取接收到字串編碼位元組,再轉換為utf-8格式的字串顯示,以呼應手機端utf-8的編碼格式。
在本例所使用的裝置環境下,只有轉換為utf-8才可以正確顯示中文,轉為其它格式都會出現亂碼。其原因應該是手機端編碼為utf-8,pc端則須相應以utf-8解碼。
這裡兩行語句的不同之處僅在於getbytes()是否帶引數,不帶引數表示以當前預設編碼格式獲取位元組陣列,帶引數表示以給出的特定編碼格式獲取字串的位元組陣列。
另外,經實驗,pc端所接收的手機端傳送來的中文資訊,再次傳回手機模擬器時不需要轉換編碼,否則手機端可能會顯示亂碼。這就出現了下面有趣的操作:
mprintwriter.println(mstrmsg + new string(" 測試".getbytes("utf-8")));
其中mstrmsg為從手機端獲取的包含漢字的資訊,發回手機時不需要轉換,而附加的漢字資訊" 測試"則需要執行轉碼操作。而且只能以new string(" 測試".getbytes("utf-8"))的方式獲取utf-8編碼位元組陣列,並生成utf-8字串;如果換成new string(" 測試".getbytes(),"utf-8")語句,則還是亂碼。
從以上分析可以看出,utf-8和gbk等之間的編碼、解碼、轉換等操作,需要非常小心,否則會出現很多意想不到的錯誤。而且,上述解決方案也並非完善,如果漢字字數為奇數時,最後乙個漢字還會是亂碼,或"??"。
究其原因,主要是gbk的漢字編碼為2位元組;而utf-8的漢字編碼則為3位元組。
為了解決奇數個漢字末尾的亂碼問題,需要採用從socket輸入流直接讀取位元組再轉碼的方式:
以下是pc端的部分**:
......
private inputstream inputstream;
......
while (true) else
} ......
手機模擬器端與此類似。
參考文章:
《android應用開發揭秘》
關於android與pc通訊時中文亂碼的分析和解決
android http中文亂碼問題總結
中文亂碼問題分析
在平時處理中文字元時經常會遇到亂碼問題,為了弄清楚其中原因,做了個實驗。在實驗前需要先了解幾個概念 1 ansi編碼 ansi不是一種具體的編碼方式,它依賴於當前系統使用的碼表,在命令列中使用chcp命令可以獲取到系統當前使用的碼表。vs新建的專案預設使用ansi編碼。2 原始檔編碼 vs新增的檔案...
vim中文亂碼分析解決
vim裡面的編碼主要跟三個引數有關 enc encoding fenc fileencoding 和fencs fileencodings 其中fenc是當前檔案的編碼,也就是說,乙個在vim裡面已經正確顯示了的檔案 前提是你的系統環境跟你的enc設定匹配 你可以通過改變 fenc後再w來將此檔案存...
Mysql中文亂碼問題分析
1.jsp頁面出問題 2.資料庫連線出問題 jdbc mysql 3.資料庫編碼與客戶端不一致 先檢視下show variables like char 在my.ini中新增 mysql 設定mysql客戶端預設字符集 default character set utf8 mysqld 設定3306...