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

本文探讨了在客户端处理服务器信息时遇到的readLine()阻塞问题,提供了三种解决方案:服务器添加换行符、使用Read()方法和DataInputStream。重点在于如何确保数据完整接收,适用于服务器维护者或开发者面对类似问题的参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

只能说基础不牢吧,代码逻辑一切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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值