java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java Socket循环接收数据readLine()阻塞

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

作者:曲幽

这篇文章主要介绍了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();
}

总结

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

您可能感兴趣的文章:
阅读全文