在传统的阻塞线程服务器中,我会像这样做:
class ServerSideThread {
ObjectInputStream in;
ObjectOutputStream out;
Engine engine;
public ServerSideThread(Socket socket, Engine engine) {
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
this.engine = engine;
}
public void sendMessage(Message m) {
out.writeObject(m);
}
public void run() {
while(true) {
Message m = (Message)in.readObject();
engine.queueMessage(m,this); // give the engine a message with this as a callback
}
}
}
现在,预计对象会非常大。在我的nio循环中,我不能简单地等待对象进入,否则所有其他连接(工作负载小得多)都将在等待我。
我该如何才能在通知我的nio通道就绪之前,仅收到一个连接具有完整对象的通知?
new ObjectOutputStream(new ByteArrayOutputStream)
来处理每个对象(或一组对象),这样就不会有数据排队。您可以发送字节数组的长度作为一个int
,然后是字节数组本身。在读取方面,您需要读取至少4个字节,以获取对象数据的其余部分的长度。 - Peter Lawreynew ObjectOutputStream()
将每个对象与单个ObjectOutput/InputStream
对一起使用时,应该注意两个微妙的陷阱:首先,只需要发送一次的数据(例如头文件和有关类型的各种元信息)会在每次发送时重新发送。其次,在多次发送时,发送方常见实例成为不同的引用。 - antak