1. 程式人生 > >Java的Socket通訊的read阻塞和亂碼問題

Java的Socket通訊的read阻塞和亂碼問題

  這兩天一直再研究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寫的,客戶端是用易語言。