[英]Input Stream getting filled with null data
因此,我正在创建一个试图处理ASCII数据的服务器。 虽然我可以让Streams正常工作并调用方法。 但是,用于将项目添加到队列( ArrayBlockingQueue
)的侦听线程,它将一直循环直到队列中充满了空数据。
服务器代码,客户端处理程序(压缩,如果遗漏了,让我知道。):
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. */
}
}
}
我的问题:是什么导致“侦听”线程循环并无限添加空数据到队列?
虽然我知道这不是Code Review的交流,但是如果有人可以想到更好的类来利用,而他们却只能提及它。
编辑:
根据建议,我将队列从ArrayList<>
更改为ArrayBlockingQueue
。
IOUtils.toByteArray()
不适合这种用法。 它将读取到流的末尾并返回一个大字节数组,而不是消息序列。 因此,两次调用或循环调用肯定没有意义。 得到初始结果之后,您可以获得的是无限个空字节数组。
我没有使用过IOUtils.toByteArray
但是我怀疑如果调用它时流中没有数据,则它会返回null或一个空数组。
如果考虑一下,这是有道理的,因为否则它不知道要读取多少字节。 它无法知道是否要发送包含1、4或1000个字节的数组,因此它仅在调用时读取已准备就绪的所有内容。
您需要以某种方式在每次调用toByteArray
之间休眠,并忽略任何空响应。 更好的方法是查看是否可以休眠,直到更多数据到达套接字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.