gpt4 book ai didi

java - 在 Java 中使用阻塞 NIO

转载 作者:行者123 更新时间:2023-12-01 09:57:01 25 4
gpt4 key购买 nike

我只是想知道是否可以使用 SocketChannel 类(带有 ByteBuffer)来模拟 Java 中常规 Socket 类的阻塞功能。我做了两个测试项目,一个模拟客户端,另一个模拟服务器:

客户端代码:

    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,而更改为 -1 或 4(字节)分别为整数)。

至于服务器端,我知道我可以让它等待,以便第二个 socketCh.read(buffer) 返回 -1 以外的值,这意味着 SocketChannel 中没有写入任何内容(我推测)。

但是,在客户端,我没有任何想法。

我知道我可以使用 DataOutputStream 和 DataInputStream 并以老式方式进行操作,但为了方便起见,我想知道如何使用 SocketChannels 进行操作。此外,您还有其他绝招,不会出错。

尽管我手动将服务器配置为阻塞,但我认为它是默认配置,因此可以丢弃它。

提前谢谢您!PS:希望我可以避免使用 Selector 类来完成这样一个简单的任务......

编辑:我知道选择器类只能用于非阻塞模式。

最佳答案

您正在丢弃可能已读取的额外数据,并假设每次读取都准确地传送与每次写入相对应的数据(例如,第一个读取仅传送 int)。 TCP 中没有任何内容可以保证这一点。

rewind()更改为flip();将 clear() 更改为 compact();添加对 read() 返回值的一些检查;它应该按预期工作。

您无法在阻塞模式下使用Selector

关于java - 在 Java 中使用阻塞 NIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37123402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com