簡體   English   中英

java.nio.channels.ServerSocketChannel無法正確關閉

[英]java.nio.channels.ServerSocketChannel not closing properly

我有一個java.nio.channels.ServerSocketChannel ,其初始化如下:

while(true)
{
    ServerSocketChannel channel = ServerSocketChannel.open();
    InetSocketAddress serverSocket = new InetSocketAddress(host,port);
    channel.bind(serverSocket);
    SocketChannel ch = channel.accept();

    // Later on when I have read off data from a client, I want to shut this 
    // connection down and restart listening.
    channel.socket().close(); //Just trying to close the associated socket 
    // too because earlier approaches failed
    channel.close();
}               

當我從客戶端發送第一條消息時,它已成功傳遞到服務器,並且客戶端程序退出 然后麻煩開始了。 當我再次初始化客戶端並嘗試建立與第一次相同的服務器端口和地址時,

java.net.BindException:地址已在使用中:connect

即使我關閉了關聯的通道/套接字也是如此。 我一直在更新ServerSocketChannelInetSocketAddress對象,因為在寫入之后我的客戶端實例必須關閉,因此我必須脫離該通道,並且由於關閉該通道后無法重用該通道,因此每次都必須創建一個新對象。 我的理論是,由於每次都重新分配channel引用,孤立的對象變成GC的主角,但是由於close()方法顯然無法正常工作,通道仍然有效,直到GC收集到我的端口為止。 盡管如此,我還是嘗試在while循環之前保留ServerSocketChannelInetSocketAddress對象的初始化,但這並沒有幫助,並且第一次寫入后發生了與以前相同的異常。

 ServerSocketChannel channel = ServerSocketChannel.open();
 InetSocketAddress serverSocket = new InetSocketAddress(host,port);
 channel.bind(serverSocket);

 while (true)
 {
    SocketChannel ch = channel.accept();
    //read from a client
 }              

為了清楚起見,這是我如何從客戶端進行連接:

        SocketChannel ch=SocketChannel.open();
        ch.bind(new InetSocketAddress("localhost", 8077));
        InetSocketAddress address=new InetSocketAddress("localhost",8079);
                    //the address and port of the server
        System.out.print(ch.connect(address));
        ByteBuffer buf=ByteBuffer.allocate(48);
        buf.clear();
        buf.put("Hellooooooooooooooooooooooooo".getBytes());
        buf.flip();
        while(buf.hasRemaining()) {
            ch.write(buf);
        }
        ch.close();

看來您在混淆客戶端和服務器。 通常,服務器僅啟動一次並將s bind到s端口。 通常,由於程序退出時端口被釋放,因此無需close任何內容。 顯然,您必須關閉由ServerSocket.accept()獲得的Socket ,但這是另一回事了。

我想您對變量名感到困惑(就像我剛開始時遇到的那樣)。 嘗試根據事物的類型來調用所有事物,這對匈牙利人真的很有幫助。


我為測試此代碼而編寫的代碼又長又笨又無聊。 但這似乎有效。

這樣做可能也會有所幫助:

channel.setOption(StandardSocketOptions.SO_REUSEADDR,true);

搜索有關此選項的信息以了解更多信息。

還要執行ch.close()來GC客戶端套接字。

暫無
暫無

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

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