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();
}

总结

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

相关文章

  • java设计简单学生管理系统

    java设计简单学生管理系统

    这篇文章主要为大家详细介绍了java设计简单学生管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • IDEA全量替换一次性解决旧项目并将所有文件换行符改为LF问题

    IDEA全量替换一次性解决旧项目并将所有文件换行符改为LF问题

    这篇文章主要介绍了IDEA全量替换一次性解决旧项目并将所有文件换行符改为LF问题,非常不错,具有一定的参考借鉴价值,需要的朋友参考下
    2019-05-05
  • java实现登录之后抓取数据

    java实现登录之后抓取数据

    这篇文章给大家分享了用JAVA实现在登陆以后抓取网站的数据的相关知识,有兴趣的朋友可以测试参考下。
    2018-07-07
  • JavaMailSender实现邮箱验证功能

    JavaMailSender实现邮箱验证功能

    本篇文章主要给大家介绍了JavaMailSender实现邮箱注册验证的功能实现原理以及其中遇到的问题,一起跟着学习探讨下吧。
    2017-12-12
  • 详解MyBatis-Plus Wrapper条件构造器查询大全

    详解MyBatis-Plus Wrapper条件构造器查询大全

    这篇文章主要介绍了详解MyBatis-Plus Wrapper条件构造器查询大全,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • ElasticSearch创建后索引修改数据类型方法步骤

    ElasticSearch创建后索引修改数据类型方法步骤

    Elasticsearch存储数据之前需要先创建索引,类似于结构型数据库建库建表,创建索引时定义了每个字段的索引方式和数据类型,这篇文章主要给大家介绍了关于ElasticSearch创建后索引修改数据类型的方法步骤,需要的朋友可以参考下
    2023-09-09
  • Java实现的zip压缩及解压缩工具类示例

    Java实现的zip压缩及解压缩工具类示例

    这篇文章主要介绍了Java实现的zip压缩及解压缩工具类,结合实例形式分析了java对文件的进行zip压缩及解压缩的具体操作技巧,需要的朋友可以参考下
    2018-01-01
  • Java线程的调度与优先级详解

    Java线程的调度与优先级详解

    这篇文章主要为大家详细介绍了Java线程的调度与优先级,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 解决Spring国际化文案占位符失效问题的方法

    解决Spring国际化文案占位符失效问题的方法

    本篇文章主要介绍了解决Spring国际化文案占位符失效问题的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Netty核心功能之数据容器ByteBuf详解

    Netty核心功能之数据容器ByteBuf详解

    这篇文章主要为大家介绍了Netty核心功能之数据容器ByteBuf详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10

最新评论