【问题标题】:Java: How to confirm if a port is open?Java:如何确认端口是否打开?
【发布时间】:2017-08-30 00:24:11
【问题描述】:

我看过其他帖子,但没有一个是这么具体的。如果它是重复的,标记它,我会删除它。

我想知道如何确认 TCP 端口是否打开......显然,我正在创建一个套接字并将 connect() 调用到指定的 InetAddress 和端口号。我的测试表明,如果端口不开放,会抛出IOException,如果端口开放,则不会出现异常。

异常捕获是检查端口是否打开的唯一方法吗? 另外,或许更重要的是,如果没有抛出异常,并且执行了connect()之后的那一行,是不是说明整个TCP连接是完整且成功的呢?我问是因为显然 isConnected() 在某些情况下并不总是返回预期的结果,所以我不确定它是否可靠。我是否需要实际读取或写入某些内容到端口以进行确认?

【问题讨论】:

    标签: java networking tcp network-programming port


    【解决方案1】:

    Java NIO 提供异步套接字编程,它将异常作为参数返回,这意味着如果套接字未打开,将引发异常。如果您有很多嵌套调用并且关心堆栈跟踪的大小,这可能会更可取。

    在 TCP/IP 握手完成之前,低级别(内核)套接字连接函数不会返回,因此您可以假设套接字已打开并可以使用。无法知道套接字是否真正打开,因为例如连接的另一端可能出现服务中断,这可能会阻止另一端通知您的应用程序连接已关闭。因此,可以知道连接是否关闭,如果您收到了 FIN 数据包,但无法知道它是否打开。如果建立了连接,您可以假设它是打开的,但没有应用层握手,则无法知道连接是否曾经打开。一些应用层协议发送频繁的无操作消息以确保套接字仍然打开,这有助于根据在特定超时时间内未收到数据包已收到的 ACK(通知)来确定连接是否关闭,但网络延迟可能实际上会导致超时给出误报。使用超时,您假设它已关闭,并且由于握手而连接后您假设它是打开的,但唯一可以确定的是,如果您在 TCP 层收到 FIN 消息,则套接字肯定是关闭的。

    【讨论】:

    • 端口扫描器在多大程度上完成了一次握手?不确定我是否将此与另一种技术混淆,但我认为他们会发送一个 SYN 但从不发送一个 ACK​​,因此它不能被视为已确认的连接(以防止被我认为的服务器记录)。
    • 有一些库供 Java 打开原始套接字,但同步扫描的目的与安全性更相关,因为通过某些防火墙配置可以确定套接字已打开但被防火墙阻止.简单地发送一个 SYN 不是一个完整的连接,因此不可能通过该连接发送数据。
    • 在我标记你的答案之前,重复一遍,没有办法在不发送数据的情况下确认套接字/端口连接是否完整。但是在正常情况下,如果使用Java sockets类调用socket.connect()时没有抛出异常,则可以认为端口是开放的。
    • 一旦连接返回没有错误,你可以假设连接是打开的,或者至少打开了足够长的时间让它发送 SYN/ACK,但唯一的方法是知道接收者是否收到了 ACK完成连接是发送一些数据,一旦有数据的 ACK,你就知道接收方的端口是打开的。
    猜你喜欢
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 2023-03-07
    • 2012-08-03
    • 2013-10-12
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多