Java Scala中的端口扫描:应用程序因远程主机上的关闭端口而挂起
我一直在尝试创建一个应用程序,它需要尽可能快地扫描网络(主要是LAN)上打开的端口 我四处搜索,发现一个很棒的方法使用了以下代码:Java Scala中的端口扫描:应用程序因远程主机上的关闭端口而挂起,java,scala,port,Java,Scala,Port,我一直在尝试创建一个应用程序,它需要尽可能快地扫描网络(主要是LAN)上打开的端口 我四处搜索,发现一个很棒的方法使用了以下代码: (1 to 65536).par.map { case port ⇒ try { val socket = new java.net.Socket("127.0.0.1", port) socket.close() println(port) port } catch { case _: Throwable ⇒ -1
(1 to 65536).par.map { case port ⇒
try {
val socket = new java.net.Socket("127.0.0.1", port)
socket.close()
println(port)
port
} catch {
case _: Throwable ⇒ -1
}
}.toSet
但是,代码的问题是,如果输入127.0.0.1或localhost以外的任何内容作为位置(比如192.168.1.2),应用程序将冻结
你知道为什么会发生这种情况,以及我如何解决它吗
另外,我还尝试使用socket.setSoTimeout(1500)设置套接字超时,但没有改变
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._
import scala.util.Try
import scala.concurrent._
import java.util.concurrent.Executors
implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(100))
def openPorts(address:String ="127.0.0.1",duration:Duration = 10 seconds, fromPort:Int = 1, toPort:Int = 65536) = {
val socketTimeout = 200
val result = Future.traverse(fromPort to toPort ) { port =>
Future{ Try {
val socket = new java.net.Socket()
socket.connect(new java.net.InetSocketAddress(address, port),socketTimeout)
socket.close()
port
} toOption }
}
Try {Await.result(result, duration)}.toOption.getOrElse(Nil).flatten
}
scala> val localPorts openPorts(fromPort = 10, toPort = 1000)
localPorts: scala.collection.immutable.IndexedSeq[Int] = Vector(22, 631)
scala> val remotePorts = openPorts(fromPort = 10, toPort = 1000, address="192.168.1.20")
remotePorts: scala.collection.immutable.Seq[Int] = List() //we ate the timeout
scala> val remotePorts = openPorts(fromPort = 12000, toPort = 13000, address="91.190.218.61", duration=30 seconds)
remotePorts: scala.collection.immutable.Seq[Int] = Vector(12345, 12350)
虽然Ashalynd的答案也很有效,但当我再次使用这个应用程序时,我发现了一个解决方案,可能更简单,使用Futures 这是密码
import scala.concurrent._
import ExecutionContext.Implicits.global
object TestOne extends App{
println("Program is now running")
val dataset: Future[Set[Int]] = future {
(1 to 6335).map {
case port =>
try {
val socket = new java.net.Socket("127.0.0.1", port)
socket.close()
println("The port is open at " + port)
port
} catch {
case _: Throwable => -1
}
}.toSet
}
}
建立连接时,会阻止等待,直到远程主机响应或连接尝试超时。在您的情况下,尝试连接到不存在的主机意味着您将花费所有时间等待超时。与任何程序一样,如果不忽略异常,您会意识到这一点。@kdgregory我尝试设置socket.setSortimeout(3000),但也不起作用。3秒乘以65536仍然是很长的时间。您和投票支持您的人需要阅读一些文档。“平行”并不意味着“无限的线”。人们在问问题来学习。没问题,谢谢你的回答。我一直在检查Futures API,它似乎非常有用。与我的解决方案不同的是,您仍然按顺序查看端口列表,而Future.traverse可以并行执行(当然,如果相应地配置了执行上下文)。是的,您是对的。谢谢你的回答。当我问这个问题的时候,我对Scala还不熟悉,并且更了解像JS这样的脚本语言的并发模型。我使用Scala Futures已经有一段时间了,现在我明白了为什么您的解决方案更好。