我只是想知道是否可以使用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()的細節,讓整個過程更加有意義。這就是我爲了掠過一本書而得到的結果,我想:\。謝謝你,真的很感激它 –