2014-04-04 140 views
1

我有一個java.nio.channels.ServerSocketChannel我初始化如下: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:地址已在使用:連接

即使我關閉了關聯的通道/套接字。 我一直在更新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(); 

回答

3

它看起來像你混淆客戶端和服務器。通常情況下,服務器只啓動一次並且bind s到端口。通常,當程序退出時,不需要任何任何端口被釋放的東西。顯然,您必須關閉ServerSocket.accept()獲得的Socket,但這是另一回事。

我想你已經對你的變量名稱感到困惑(就像我在開始時發生的那樣)。嘗試根據其類型調用所有的東西,這裏是匈牙利語對我真的很有幫助。


code我寫的測試這是漫長,愚蠢和無聊。但它似乎工作。

+0

這絕對是香草插座中的情況。然而在nio中看起來很奇怪。我會盡量多關注變量名稱。 – zafar142003

+1

我不知道我是否知道我在說什麼...所以我試了一下,綁定和關閉'ServerSocketChannel'似乎工作。即使是一些溝通。當我擦亮一下時,我會把它鏈接起來。 – maaartinus

+0

如果在您的試用期中服務器可能會從客戶端接收多次的流量(客戶端關閉其他連接等後),如果您提到它的完成情況,我將不勝感激。 – zafar142003

-3

do ch.close()以及GC客戶端套接字。

+0

你的意思是除了channel.close()和channel.socket()。close()? – zafar142003

+0

yes correct..try it .. –

+0

沒有工作,那個,同樣的異常:( – zafar142003