TCP 长连接小尝试

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)


猜你喜欢

转载自blog.csdn.net/xyjincan/article/details/69357504
今日推荐