• Java Socket 循环接收数据readLine()阻塞问题解决办法


    写在前面

    只能说基础不牢吧,代码逻辑一切OK,就是接收不到服务器信息,发送没问题。
    因为服务器不是我能控制的,只能在客户端想办法解决,后来断点知道了readLine()阻塞的情况,大无语呀,阻塞好是好,但你要换行符,我哪知道服务器给的是什么。

    这里socket的连接之类的代码很多,就不重复贴了,只放些解决方案供有同样问题的朋友参考

    解决方案一 加换行符

    就是上面提到的readLine()要换行符才知道传送完成,所以这个只能是服务器端发送数据给客户端时,结尾一定要加个\r\n
    又或者使用 println() 发送数据
    如果服务器客户端都是你维护,那这个解决方案最简单高效。

    以下代码当个参考,m_clientSocket 即是服务端通信用Socket,非连接用的ServerSocket

     public void SendMessage(String msg) {
         new Thread(new Runnable() {
             @Override
             public void run() {
                 try {
                     if (m_clientSocket.isConnected()) {
                         if (!m_clientSocket.isOutputShutdown()) {
                             PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()), true);
                             printWriter.println(msg);
                         }
                     }
                 } catch (IOException e) {
                     log(e.getMessage());
                 }
             }
         }).start();
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    解决方案二 使用Read() 方法

    这里记得新开线程或用异步任务执行接收数据的逻辑

    private void WaitForData() {
        FutureTask<Void> futureTask = new FutureTask<>(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                try {
                    String charset = "GBK";
                    byte[] buffer = new byte[10240];
                    String msg;
                    int len;
                    InputStream inputStream = m_clientSocket.getInputStream();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charset));
                    while (true) {
                        if (!m_clientSocket.isInputShutdown()) {
                            len = inputStream.read(buffer);
                            if (len == -1) break;
                            msg = new String(buffer, 0, len, charset);
                            log(msg);
                            // 拿到了接收到的数据msg后面就是自己的处理逻辑了,是打印还是其他了
                        }
                    }
                } catch (Exception e) {
                    log(e.getMessage());
                }
                return null;
            }
        });
        new Thread(futureTask).start();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    解决方案三 DataInputStream

    这种方法好是好,但没有阻塞等待,会一直循环。(突然发现阻塞也是好东西呀)
    一并贴出来供参考吧,看需要的朋友使用

    private void WaitForData() {
        FutureTask<Void> futureTask = new FutureTask<>(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                int i = 0;
                while (true) {
                    if (!client.isInputShutdown()) {
                        try {
                            DataInputStream inputStream = new DataInputStream(client.getInputStream());
                            byte[] buffer = new byte[inputStream.available()];
                            if(buffer.length != 0){
                                inputStream.read(buffer);
                                String msg = new String(buffer);
                                clientReceiveData.OnClientReceiveData(msg);
                            }
                            i++;
                            log(String.valueOf(i));
                        } catch (Exception ee) {
                            log(ee.getMessage());
                        }
                    }
                }
            }
        });
        new Thread(futureTask).start();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    【MQTT】基于阿里云物联网平台实现两设备间相互订阅及发布消息
    应用案例|基于高精度三维机器视觉的检测汽车座椅应用
    杠杆炒股的尾盘买入法
    unity urp 衣服渲染
    广东MES系统实现设备管理的方法与功能
    webAPI学习大纲梳理(二)
    【教程】AWD中如何通过Python批量快速管理服务器?
    Mybatis—LanguageDriver
    编写基于maven的IDEA插件,实现根据现有代码生成流程图的 pom(2)
    EPOLL单线程版本 基于reactor 的 httpserver文件下载 支持多个客户端同时处理
  • 原文地址:https://blog.csdn.net/ymtianyu/article/details/126367654