【发布时间】:2016-05-10 14:21:43
【问题描述】:
我只是想知道是否可以使用 SocketChannel 类(带有 ByteBuffer)来模拟 Java 中常规 Socket 类的阻塞特性。我做了两个Test项目,一个模拟Client,另一个模拟Server:
客户代码:
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());
}
正如我在 cmets 中所说,运行服务器然后运行客户端(按此顺序)的结果是不可预测的,因为有时第二个数字可能保持为 4 或变为 6,更改为 -1 或 4(字节整数)。
至于服务器端,我知道我可以让它等待,以便第二个 socketCh.read(buffer) 返回一个非 -1 的值,这意味着(我认为)SocketChannel 中没有写入任何内容。
但是,在客户端,我没有任何想法。
我知道我可以改用 DataOutputStream 和 DataInputStream 并以老式方式执行此操作,但为了方便起见,我想知道如何使用 SocketChannels 执行此操作。此外,你也不会出错。
尽管我手动将服务器配置为阻塞,但我认为它是默认配置,因此可以丢弃它。
提前感谢您! PS:希望我可以避免在这样一个简单的任务中使用 Selector 类...
编辑:我知道 Selector 类只能用于非阻塞模式。
【问题讨论】:
标签: java nio socketchannel