Java 输入流被空数据填充

Java 输入流被空数据填充,java,multithreading,sockets,inputstream,Java,Multithreading,Sockets,Inputstream,因此,我正在创建一个服务器,试图处理ASCII数据。而我可以让流工作并调用方法。但是,侦听线程需要将项目添加到队列(ArrayBlockingQueue),它将循环,直到队列中满是空数据 服务器代码,客户端处理程序(压缩,如果我遗漏了什么,请告诉我): 我的问题:是什么导致“侦听”线程循环并无限期地向队列添加空数据? 虽然我知道这不是代码审查交换,但如果有人能想到更好的类来利用,如果他们能提到的话 编辑: 根据一项建议,我将队列从ArrayList更改为ArrayBlockingQueue我没有

因此,我正在创建一个服务器,试图处理ASCII数据。而我可以让流工作并调用方法。但是,侦听线程需要将项目添加到队列(
ArrayBlockingQueue
),它将循环,直到队列中满是空数据

服务器代码,客户端处理程序(压缩,如果我遗漏了什么,请告诉我):

我的问题:是什么导致“侦听”线程循环并无限期地向队列添加空数据?

虽然我知道这不是代码审查交换,但如果有人能想到更好的类来利用,如果他们能提到的话

编辑:


根据一项建议,我将队列从
ArrayList
更改为
ArrayBlockingQueue
我没有使用
IOUtils.toByteArray
,但我怀疑,如果调用时流中没有数据,那么它要么返回null要么返回空数组

如果您仔细考虑,这是有意义的,因为否则它不知道要读取多少字节。它无法知道您是否正在发送包含1、4或1000字节的数组,因此它只会在您调用它时读取所有准备就绪的内容


您需要在每次调用
toByteArray
之间以某种方式休眠,并忽略任何空响应。更好的方法是查看是否可以在更多数据到达套接字之前睡眠。

IOUtils.toByteArray()
不适合此用法。它将读取到流的末尾,并返回一个大字节数组,而不是一个消息序列。因此,毫无疑问,调用它两次或在循环中调用它是没有意义的。在初始结果之后,您只能得到无限多个空字节数组。

@JJF根据我所读的内容,输入流应该阻塞,直到数据可用为止。(apachecommons正在使用read方法创建字节数组。)我将查看链接。谢谢。您使用了
InputStream.read(byte[]message)
的读取方法,并收到了相同的结果。
IOUtils.toByteArray
只是
read()
Stream方法的一个掩码,所以我相信这不是问题所在。它读取到流的末尾,而不是“调用它时准备好的所有东西”@Gamerb它不是“简单地说,
read()
方法的掩码”。如果是的话,使用它就没有什么意义了。
class ClientThread extends Thread {

  // ASCII commands defined here (byte NUL=0x00; byte SOH=0x01; etc.) 

  private Socket socket;
  private InputStream sInput;
  private OutputStream sOutput;

  BlockingQueue<byte[]> queueIn = new ArrayBlockingQueue<>(30, true);

  private boolean goodToGo = false;

  ClientThread(Socket socket){

    id = ++Server.uniqueId; /* To be replaced with UIDs */
    this.socket = socket;

    /* Create Data Streams */
    try {
        sInput = (socket.getInputStream());
        sOutput= (socket.getOutputStream());
        goodToGo = true;
    } catch (IOException ex) {
        ServerInit.logger.log(Level.WARNING, "Error Openning Streams!", ex);
    } 
  }

  @Override
  public void run(){
    boolean keepGoing = true;

    System.out.println("Client thread started.");
    /* Start listening thread */
    new Thread() {
        @Override
        public void run(){
            while(goodToGo) {
                System.out.println("Listening thread looping.");
                try {
                    byte[] temp = IOUtils.toByteArray(sInput); // read client input using Apache Commons IO.
                    // Add the result to the queue.
                    queueIn.put(temp);
                } catch (EOFException eof){
                    ServerInit.logger.log(Level.INFO,"Remote client closed connection.");
                    close();
                }
                catch (IOException ex) {
                    ServerInit.logger.log(Level.WARNING, "Error Reading Stream!", ex);
                    close();
                } 
            }
        }
    }.start();

     while (keepGoing && goodToGo){
        System.out.println("Main thread looping.");
        try{

            byte[] message = queueIn.take();

            if (message.length >= 4){

               /* Message picked apart and worked with here */

            } else if (message.length == 0 ){
                // Do nothing.
            } else {
                ServerInit.logger.log(Level.WARNING, "Unable to process item from queue.");
            }
        } catch (Exception e) {
            /* Here just for completeness, I don't catch Exceptions this way. :) */
        }
     }
   }

   protected void close(){
    // try to close the conection
    goodToGo = false;
    try {
        if (sOutput != null) {
            sOutput.close();
        }
        if (sInput  != null) {
            sInput.close();
        }
        if (socket  != null) {
            socket.close();
        }

        ServerInit.SERVER.remove(id);

    } catch (Exception e){
        ServerInit.logger.log(Level.FINER, "Error closing client connections.", e);
    }
  }
}
public class TestClient{
  public static void main(String args[]){
    try{
      Socket socket = new Socket("localhost", 5525);
      OutputStream outputStream = socket.getOutputStream();
      byte[] buffer = { 0x02, 0x05, 0x07, 0x04 };

      outputStream.write(buffer);
      outputStream.flush();
      outputStream.close();
    } catch (Exception e) {
       /* Again, I don't catch exceptions like normally. */
    }
  }
}