2013-07-30 50 views
1

我寫了一個簡單的Java NIO程序像下面Java nio連接正在創建多個套接字級連接,爲什麼?

public static void main(String[] args) throws IOException, InterruptedException { 


    InetSocketAddress address = new InetSocketAddress("127.0.0.1",1001); 
    Selector incomingMessageSelector = Selector.open(); 
    SocketChannel socketChannel = SocketChannel.open(); 
    socketChannel.configureBlocking(false); 

//到這裏的代碼創建頂部2連接到端口52209和52210

socketChannel.connect(address); 
    socketChannel.register(incomingMessageSelector, SelectionKey.OP_CONNECT); 
    socketChannel.register(incomingMessageSelector, SelectionKey.OP_WRITE); 
    socketChannel.register(incomingMessageSelector, SelectionKey.OP_READ); 

//然後創建2個連接端口1001

Thread.sleep(900000L); 
} 

我想知道爲什麼它會創建4個連接,它往往會造成2個連接標準的TCP攔截庫。

我使用JDK 1.7和Windows 7

在圖像只有4個高亮顯示連接是它們由客戶端創建的興趣。

標有紅色的一個連接1條目是服務器端口。

PFA顯示這4個連接的圖像。

嗯,我實際上可以最明白的是爲什麼

Selector incomingMessageSelector = Selector.open(); 

創建一個動態端口上的連接

enter image description here

+0

這聽起來很奇怪。恕我直言,我發現阻止NIO更簡單的工作,更快,如果你有少量的連接。 –

+0

從API可能會更簡單,但是我更關注爲什麼在TCP層創建4個連接時,只有1個連接是從代碼創建的。 – Sudarshan

+0

您可以包含「端口50512和50513」的條目嗎?它們不在您的圖像中。 –

回答

1

的圖像是非常小的,但仔細調查你有

  • 兩個Java進程
  • 第一個進程與自己有連接。沒有爲每個最終它也有從第二處理端口連接的連接,端口52209和52210.
  • 第二種方法是在客戶端您正在使用一個連接到端口1001
運行
+0

是的,你是正確的。不過,我已經關閉了所有的IDE,並通過記事本運行:) ..1 java進程是使用稱爲套接字測試的工具託管的服務器,另一個java進程是我發佈的創建客戶端連接的代碼。當我關閉客戶端程序時,我留下了一個佔用端口1001(服務器程序)的java進程,並且客戶端程序創建了套接字級連接。 – Sudarshan

+0

這一切都對我有意義。考慮到表中只有一個連接用於兩個條目並且服務器上的其他連接可以被忽略,您能否重新解釋這個問題? –

+0

更新後的問題使其更清晰。我認爲總共有5個java進程條目,其中1個是服務器,4個是客戶端連接 – Sudarshan

1

1001和52211之間的連接顯示兩次,每個方向顯示一次,因爲兩個端口都是本地的。

Selector可能會打開另一個監聽套接字,以防它必須處理子選擇器,以免超過每個選擇器的最大套接字數量。

在完成OP_CONNECT pgphasr之前,您還應該註銷OP_READ或OP_WRITE,此時還應該註銷OP_CONNECT。同時登記所有三個人肯定是錯誤的。

+1

「如果選擇器必須處理子選擇器,以免超過每個選擇器的最大套接字數量,則可能會打開另一個偵聽套接字。」 - 請你詳細解釋一下這個問題......或者你可以參考一些文字,說明選擇器概念如何影響套接字層...... – Sudarshan

+0

該平臺對套接字數量有限制可以一次選擇。 Java不會:它使用通過額外套接字與主選擇器通信的子選擇器方案。當一個子選擇器準備就緒時,它將一些東西寫入套接字,這樣主選擇器就會喚醒。這是一個實現功能,除了源代碼之外,沒有任何我知道的文檔記錄。 – EJP

+0

這是否意味着選擇器可以通過其子選擇器打開多個套接字? – Sudarshan