我只是想知道是否可以使用SocketChannel类(使用ByteBuffer)来模拟Java中的常规Socket类的阻塞特性。我做了两个试验项目,一个模拟客户端和其他模拟服务器:在Java中使用阻塞NIO
客户端代码:
public static void main(String[] args) throws IOException {
SocketChannel socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 6789));
//Simulate this:
//DataOutputStream dos = new DataOutputStream(socket.socket().getOutputStream());
//dos.writeInt(4);
//dos.writeInt(6);
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.putInt(4);
buffer.flip();
socket.write(buffer);
buffer.clear();
buffer.putInt(6);
buffer.flip();
socket.write(buffer);
}
服务器代码:
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(6789));
SocketChannel socketCh = ssc.accept();
socketCh.configureBlocking(true);
// Simulate this
// DataInputStream dis = new DataInputStream(socketCh.socket().getInputStream());
// System.out.println(dis.readInt());
// System.out.println(dis.readInt());
// This is something to avoid. This is not the same as what is up above
// If the 2nd line prints -1, the 3rd prints 4
// If the 2nd line prints 4, the 3rd prints 6
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketCh.read(buffer);
buffer.rewind();
System.out.println("First number: " + buffer.getInt());
buffer.clear();
System.out.println("Change: " + socketCh.read(buffer));
buffer.rewind();
System.out.println("Second Number: " + buffer.getInt());
}
正如我在评论中说,该结果运行服务器时,客户端(按该顺序)是不可预知的,因为有时第二个数字可能会保持为4或变为6,而Change分别为-1或4(整数字节)。
至于服务器端,我知道我可以让它等待,以便第二个socketCh.read(buffer)返回一个非-1的值,这意味着什么都没有被写入(我推测)在SocketChannel中。
但是,在客户端,我没有任何想法。
我知道我可以改为使用DataOutputStream和DataInputStream并以旧式方式进行,但我想知道如何使用SocketChannel来完成此操作,只是为了方便起见。另外你也不会因为另一个诡计而出错。
尽管我手动将服务器配置为阻塞,但我认为这是默认配置,因此可以丢弃它。
预先感谢您! PS:希望我可以避免使用Selector类来完成这样一个简单的任务...
编辑:我知道Selector类只能用于非阻塞模式。
好的谢谢!是的,我知道你不能在阻塞模式下使用Selector,但是我希望避免必须将SocketChannel配置为非阻塞,并且必须为此简单任务完成所有这些。 –
现在我读了一下compact()的细节,让整个过程更加有意义。这就是我为了掠过一本书而得到的结果,我想:\。谢谢你,真的很感激它 –