2017-04-04 94 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

相关问题