在传统的阻塞线程服务器中,我会做这样的事情
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通道已准备就绪之前,如何仅通知连接已包含整个对象?
您可以将对象写入ByteArrayOutputStream,以便在发送对象之前给出长度。在接收端,请先读取所需的数据量,然后再尝试对其进行解码。
但是,您可能会发现将Object * Stream与阻塞IO(而不是NIO)一起使用会更简单,更高效
像这样编辑
public static void send(SocketChannel socket, Serializable serializable) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i=0;i<4;i++) baos.write(0);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(serializable);
oos.close();
final ByteBuffer wrap = ByteBuffer.wrap(baos.toByteArray());
wrap.putInt(0, baos.size()-4);
socket.write(wrap);
}
private final ByteBuffer lengthByteBuffer = ByteBuffer.wrap(new byte[4]);
private ByteBuffer dataByteBuffer = null;
private boolean readLength = true;
public Serializable recv(SocketChannel socket) throws IOException, ClassNotFoundException {
if (readLength) {
socket.read(lengthByteBuffer);
if (lengthByteBuffer.remaining() == 0) {
readLength = false;
dataByteBuffer = ByteBuffer.allocate(lengthByteBuffer.getInt(0));
lengthByteBuffer.clear();
}
} else {
socket.read(dataByteBuffer);
if (dataByteBuffer.remaining() == 0) {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(dataByteBuffer.array()));
final Serializable ret = (Serializable) ois.readObject();
// clean up
dataByteBuffer = null;
readLength = true;
return ret;
}
}
return null;
}
问题内容: 我的Web服务器使用通常的Java I/O和每个连接机制的线程。如今,随着用户的增加(长时间的轮询连接),他们开始屈服。但是,连接大部分处于空闲状态。尽管可以通过添加更多的Web服务器来解决此问题,但我一直在尝试对NIO实现进行一些研究。 我对此有好感。我已经阅读了基准测试,其中使用Linux中新的NPTL库的常规I / O 优于NIO。 通过Java I / O配置和使用最新的NPT
主要内容:1 创建一个AsynchronousFileChannel,2 读取数据,3 通过Future读取数据,4 通过CompletionHandler读取数据,5 写数据,5 通过Future写入数据,6 通过CompletionHandler写入数据在Java 7中,它AsynchronousFileChannel已添加到Java NIO。这样AsynchronousFileChannel 就可以从文件中异步读取数据,或将数据异步写入文件。本教程将说明如何使用AsynchronousFi
主要内容:1 打开一个DatagramChannel,2 接收数据,3 发送数据,连接到特定地址Java NIO DatagramChannel是可以发送和接收UDP数据包的通道。由于UDP是无连接的网络协议,因此默认情况下,您不能仅从DatagramChannel其他通道读取和写入内容。相反,您发送和接收数据包。 1 打开一个DatagramChannel 这是打开方式DatagramChannel: 本示例打开一个DatagramChannel,它可以在UDP端口9999上接收数据包。
主要内容:1 ServerSocketChannel的介绍,2 打开一个ServerSocketChannel,3 关闭ServerSocketChannel,4 监听传入的连接,5 非阻塞模式1 ServerSocketChannel的介绍 Java NIO ServerSocketChannel是一个通道,可以侦听传入的TCP连接,就像ServerSocket在标准Java Networking中一样。该ServerSocketChannel班位于java.nio.channels包。 这是
主要内容:1 打开一个SocketChannel,2 关闭一个SocketChannel,3 从SocketChannel读取,4 写入SocketChannel,5 非阻塞模式Java NIO SocketChannel是连接到TCP网络套接字的通道。它与Java NIO等效于Java Networking的Sockets。有两种SocketChannel创建方法: 您打开一个SocketChannel并连接到Internet上某个服务器。 SocketChannel可以当传入连接到达一个被创
主要内容:1 打开一个文件通道,2 从文件通道读取数据,3 将数据写入文件通道,4 关闭文件通道,5 FileChannel的position()方法,6 FileChannel的size()方法,7 FileChannel的truncate()方法,8 FileChannel的force()方法Java NIO FileChannel是连接到文件的通道。使用文件通道,您可以从文件读取数据,也可以将数据写入文件。Java NIO FileChannel类是NIO的一种替代方法,它可以使用标准Ja