Java Socket循环接收数据readLine()阻塞的解决方案

 更新时间:2024年08月13日 08:38:16   作者:曲幽  
这篇文章主要介绍了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();
 }

解决方案二 使用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();
}

解决方案三 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();
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • @ConfigurationProperties遇到的坑及解决

    @ConfigurationProperties遇到的坑及解决

    这篇文章主要介绍了解决@ConfigurationProperties遇到的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 浅谈java内存管理与内存溢出异常

    浅谈java内存管理与内存溢出异常

    下面小编就为大家带来一篇浅谈java内存管理与内存溢出异常。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Java读取OpenSSL生成的PEM公钥文件操作

    Java读取OpenSSL生成的PEM公钥文件操作

    这篇文章主要介绍了Java读取OpenSSL生成的PEM公钥文件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • 详解Java异常处理中finally子句的运用

    详解Java异常处理中finally子句的运用

    这篇文章主要介绍了Java异常处理中finally子句的运用,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • idea没法识别springboot项目的原因解决及办法

    idea没法识别springboot项目的原因解决及办法

    IDEA无法识别Spring Boot项目可能是由于Lombok依赖未正确解析所致,原pom.xml中未指定Lombok版本号,导致依赖下载失败,下面就来详细的介绍一下解决方法,感兴趣的可以了解一下
    2025-09-09
  • 使用Feign调用注解组件(实现字段赋值功能)

    使用Feign调用注解组件(实现字段赋值功能)

    这篇文章主要介绍了使用Feign调用注解组件(实现字段赋值功能),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 浅析springboot通过面向接口编程对控制反转IOC的理解

    浅析springboot通过面向接口编程对控制反转IOC的理解

    这篇文章主要介绍了springboot通过面向接口编程对控制反转IOC的理解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-08-08
  • mybatis-plus使用generator实现逆向工程

    mybatis-plus使用generator实现逆向工程

    mybatis-plus-generator在3.5.0以及以后的版本使用新的方式逆向生成代码,本文主要介绍了mybatis-plus使用generator实现逆向工程,具有一定的参考价值,感兴趣的可以了解一下
    2022-05-05
  • SpringBoot中获取真实客户端IP的终极方案

    SpringBoot中获取真实客户端IP的终极方案

    在日常开发中,获取客户端IP看似简单,实则暗藏玄机,今天,小编将彻底揭秘Spring Boot中获取真实客户端IP的正确姿势,让你避开所有的坑
    2026-01-01
  • Java异常处理实例教程

    Java异常处理实例教程

    这篇文章主要为大家分享一份非常详细的Java异常处理实例教程,帮助大家更好的学习java异常处理,感兴趣的小伙伴们可以参考一下
    2016-02-02

最新评论