TCP 長連接小嚐試

版權聲明:本文爲博主原創文章,轉載請保留出處 https://blog.csdn.net/xyjincan/article/details/69357504

TCP 長連接小嚐試,demo

本文學習了這兩天看了不少tcp的使用細節,也看了不少有用的前輩經驗,這裏只是簡單總結一下,有些奇怪的地方,BufferedReader,sendUrgentData。

  • 面臨的問題是:寫一個第三方程序信息接收服務器,協議上完全被動,等待連接接收消息。

服務端主要邏輯更新

堵塞的(BufferedReader)讀取每條信息
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;

        try {
            // 獲取一個輸入流,接收服務端的信息
            inputStream = (InputStream) socket.getInputStream();
            // 包裝成字符流,提高效率,如果有亂碼問題
            inputStreamReader = new InputStreamReader(inputStream, "xxx");
            bufferedReader = new BufferedReader(inputStreamReader);

            char[] rcchar = new char[REVEIVEBUFFERSIZE];
            while (run) {//長連接讀取遠程信息,當連接斷開會拋出異常
                int len = bufferedReader.read(rcchar);
                if(len==-1){//連接中斷,,,           
                    throw new Exception("read socket err");
                }
                String crtstr = String.valueOf(rcchar, 0, len);
                System.out.println(new Date() + " : " + crtstr);
            }

        } catch (Exception e) {
            //與客戶端連接中斷
            try {
                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
                socket.close();
            } catch (IOException e1) {
            }
        }

服務端主要邏輯

當serversocket接收到連接時,開啓一個線程服務,非堵塞讀取

class XXXConnect extends Thread {
    // 定義系統信息接收延遲:一秒
    private static final int receiveDelayMS = 1000;
    // 接收緩存8k,可能含多條數據,粘包等等。
    private static final int REVEIVEBUFFERSIZE = 1024 * 8;


    private Socket socket;
    private InputStream in;
    private boolean run = true;
    private byte[] receiveData = new byte[REVEIVEBUFFERSIZE];

    public XXXConnect(Socket socket) {

        this.socket = socket;
        try {
            in = socket.getInputStream();
        } catch (IOException e) {
            run = false;
            try {
                socket.close();
            } catch (IOException e1) {
            }
        }
    }

    @Override
    public void run() {
        try {
            while (run) {
                // 從遠程讀取數據時,遠程連接斷開將拋出異常
                //(Software caused connection abort: recv failed)
                int len = in.read(receiveData, 0, REVEIVEBUFFERSIZE);
                if (len != -1) {
                    System.out.println(new Date() 
                        + "receive:" + new String(receiveData, 0, len));
                }
                Thread.sleep(receiveDelayMS);
                // 測試:異常表明遠程連接斷開:Connection reset by peer: send
                // 發送任意數據:測試連接是否正常(心跳)
                socket.sendUrgentData(0xFF);
            }
            socket.close();
        } catch (Exception e) {

        }
    }

}

客戶端發送測試

多次發送數據,然後服務端接收

            // 創建Socket對象
            Socket socket = new Socket("127.0.0.1", 11101);
            // 根據輸入輸出流和服務端連接
            OutputStream outputStream = (OutputStream) socket.getOutputStream();// 獲取一個輸出流,向服務端發送信息
            PrintWriter printWriter = new PrintWriter(outputStream);// 將輸出流包裝成打印流
            int ccc = 40;
            while (ccc > 0) {
                //Thread.sleep(1200);
                printWriter.print("服務端你ashfgehjsfbehjdsfbsjffj219278 27 3 好,我是Balla_兔子");
                printWriter.flush();
                ccc--;
            }

            Thread.sleep(10000);//等待那邊服務器接收玩消息退出,
            System.out.println("bye server");
            printWriter.close();
            outputStream.close();
            socket.close();

這些寫完後,發現了一個問題發送sendUrgentData 影響對方的報文接收。

            int ccc = 30;
            while (ccc > 0) {
                socket.sendUrgentData(0xFF);
                printWriter.print(ccc +  "服務端你ashfgehjsfbehjdsfbsjffj219278 27 3 好,我是Balla_兔子");
                printWriter.flush();
                //Thread.sleep(3000);
                ccc--;
            }
  1. windows下,如果A給B,發送一段報文,同時也發送多次socket.sendUrgentData(0xFF) ,B接收到的報文會缺失部分。
  2. 我又試了試linux下,如果A給B,發送一段報文,同時也發送多次socket.sendUrgentData(0xFF) ,A接收到的報文會混入未知字符。

    Microsoft Windows [版本 10.0.14393]
    java version “1.8.0_91”
    Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
    Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

    Linux 4.10.6-200.fc25.x86_64 #1 SMP Mon Mar 27 14:06:23 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    java version “1.8.0_111”
    Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
    Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章