簡體   English   中英

在Java中使用阻止NIO

[英]Using Blocking NIO in Java

我只是想知道是否可以使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM