Java的Socket通訊的read阻塞和亂碼問題
阿新 • • 發佈:2019-01-14
這兩天一直再研究TCP通訊這一塊,因為自己再做一個後臺系統,寫出的日誌想傳送的服務端(Server),大神都推薦我用netty去寫,但是我發現並沒有必要(我懶得看),一開是讀取資料的時候是這樣寫的:
in = socket.getInputStream(); BufferedInputStream reader = new BufferedInputStream(in); ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); byte[] buffer = new byte[512]; int len =0; System.out.println(reader.read(buffer)); while((len=in.read(buffer)) == -1){ bytesOut.write(buffer, 0, len); System.out.println(new String(new String(buffer,0,len).getBytes("utf-8"),"GBK")); System.out.println(bytesOut.toString("gb2312")+len); }
可以讀取到資料,但是讀取之後就再while中跳不出來,就是俗稱的read阻塞,這個原因就是你有資料他就讀,沒資料就停那,直到你設定的connectTime超時,報了一個connect time out的異常,我很無奈,研究了一上午,也去論壇問了,可能是我沒有表達清楚我的意思,也沒有得到很好的回答,這是大神的:
InputStream inputStream = socket.getInputStream(); // 得到一個輸入流,接收客戶端傳遞的資訊 InputStreamReader inputStreamReader = new InputStreamReader( inputStream);// 提高效率,將自己位元組流轉為字元流 BufferedReader bufferedReader = new BufferedReader( inputStreamReader);// 加入緩衝區 String temp = null; String info = ""; while ((temp = bufferedReader.readLine()) != null) { info += temp; System.out.println("已接收到客戶端連線"); System.out.println("服務端接收到客戶端資訊:" + info + ",當前客戶端ip為:" + socket.getInetAddress().getHostAddress()); }
額。。。還是達不到自己想要的,然後我又查了一下百度,修改之後,讀取完資料就close了,非常開心,
while (true){ if ((len = in.read(buffer)) != -1) { String text = new String(buffer, 0, len); bytesOut.write(buffer,0,len); System.out.println("server:" + text); break; } }
但是問題來了,打印出來的結果是server:����,????
因為我再服務端傳遞的是中文,試了一下解碼好像不行,大神說的是已非原本編碼去解碼,就是一條不歸路,但是我也不能放棄,之後我就想,如果再服務端把資料轉換成十六進位制或者二進位制,客戶端再進行轉換不久歐克了,下面是程式碼:
//將二進位制字串轉換成int陣列
public int[] BinstrToIntArray(String binStr) {
char[] temp=binStr.toCharArray();
int[] result=new int[temp.length];
for(int i=0;i<temp.length;i++) {
result[i]=temp[i]-48;
}
return result;
}
//將二進位制轉換成字元
public char BinstrToChar(String binStr){
int[] temp=BinstrToIntArray(binStr);
int sum=0;
for(int i=0; i<temp.length;i++){
sum +=temp[temp.length-1-i]<<i;
}
return (char)sum;
}
public void BinstrToStr(String binStr){
String[] tempStr=binStr.split(" ");
char[] tempChar=new char[tempStr.length];
for(int i=0;i<tempStr.length;i++) {
tempChar[i]=BinstrToChar(tempStr[i]);
}
System.out.println(String.valueOf(tempChar));
}
char[] strChar=reqData.toCharArray();
String result="";
for(int i=0;i<strChar.length;i++){
result +=Integer.toBinaryString(strChar[i])+ " ";
}
System.out.println(result.replace(" ",""));
new TCPUtil().BinstrToStr(result);
完美解決了,服務端我是用java寫的,客戶端是用易語言。