2017-04-04 95 views
0

我已經看過其他帖子,但沒有一個是特定的。如果它是重複的,將其標記爲這樣,我將刪除它。Java:如何確認端口是否打開?

我想知道如何確認一個TCP端口是否打開或顯然,我正在創建一個套接字並調用connect()到指定的InetAddress和端口號。我的測試表明,如果端口未打開,則拋出IOException,並且如果端口處於打開狀態,則不會出現異常。

捕獲異常是檢查端口是否打開的唯一方法嗎? 此外,也許更重要的是,如果沒有拋出異常並執行connect()後的行,那麼這是否意味着整個TCP連接已完成併成功?我在問,因爲顯然isConnected()在某些情況下並不總是返回預期的結果,所以我不確定它是否可靠。我是否需要實際閱讀或寫信給港口以進行確認?

回答

0

Java NIO提供異步套接字編程,它將返回異常作爲參數,這意味着如果套接字未打開,將引發異常。如果你有很多嵌套調用並且擔心堆棧跟蹤的大小,這可能會更好。

在TCP/IP握手完成之前,低級別(內核)套接字連接函數不會返回,因此您可以使用假設套接字已打開並可供使用。無法知道套接字是否真正打開,因爲例如在連接的另一端可能存在服務中斷,這可能會阻止另一端通知應用程序連接已關閉。因此,如果您已收到FIN數據包,但無法知道連接是否已關閉,則可能知道該連接是否已關閉。如果建立連接,則可以假定它已打開,但缺少應用層握手,則無法知道連接是否已打開。某些應用層協議會頻繁發送無操作消息,以確保套接字仍處於打開狀態,從而有助於根據未收到在特定超時時間內接收到數據包的ACK(nowledgement),找出連接是否已關閉,但網絡延遲可能會實際上會導致超時給出誤報。使用超時你假設它是關閉的,並且在由於握手而連接之後,你認爲它是開放的,但唯一可以肯定的是,如果你在TCP層收到FIN消息,那麼套接字肯定是關閉的。

+0

端口掃描器在多大程度上完成握手?不知道我是否與另一種技術混淆,但我認爲他們會發送一個SYN,但從來沒有一個ACK,因此它不能被視爲已確認的連接(以防止被我認爲的服務器記錄)。 – user58446

+0

有用於Java的庫可以打開原始套接字,但是syn掃描的目的是與安全性相關的,因爲有些防火牆配置可以確定套接字是打開的但是被防火牆阻止。簡單地發送SYN不是一個完整的連接,所以不可能通過該連接發送數據。 –

+0

在我標記你的答案之前,只需重複一遍,在沒有發送數據的情況下無法確認套接字/端口連接是否完成。但在正常情況下,如果在使用Java套接字類調用socket.connect()時沒有拋出異常,則可以將該端口假定爲開放。 – user58446

相關問題