套接字连接的惯用异常处理
Idiomatic exception handling for socket connection
我正在尝试了解如何优雅地使用 scala.util.control.Exception
包。
更具体地说,我想将这段 Java 代码转换为功能方式:
public static boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
我可以在 Scala 中使用 try-catch-finally 做同样的事情,但我正在寻找更实用的方法。另请注意,此 Java 代码使用 try-with-resources
,因此这意味着此代码无论如何都会关闭套接字(即使发生异常):socket.close()
---根据问题澄清进行编辑---
要在 scala 中以函数式风格使用自动资源管理,最简单的方法是使用 scala-arm 然后你可以写
import resource._
def hostAvailabilityCheck():Boolean= {
managed(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).map(_=>true).opt.isDefined
}
如果您真的非常想使用 scala.util.control.Exception
,您可以这样写:
import scala.util.control.Exception._
def hostAvailabilityCheck():Boolean= {
catching[IOException].opt(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)). isDefined
}
return false;
}
更好的是,您可以使用 Try
类型来执行此操作,在这种情况下,您的原始方法将变为:
def hostAvailabilityCheck():Boolean = {
Try(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).isSuccess
}
从你的例子中不清楚你想用这个做什么,但它可能对 return Try
而不是布尔值有用,这样如果端口获取成功后,您不必等待 OS 级别的端口回收,然后再以更明确的方式重新绑定它。
def hostAvailabilityCheck(port: Int):Try[Socket] = {
Try(new Socket(SERVER_ADDRESS, port))
}
然后您的客户端代码可以尝试获取一个端口,直到它真正获得一个:
def acquire(port: Int):Socket={
hostAvailabilityCheck(port).recoverWith(case t:Throwable => acquire(port)).get
}
这是一个幼稚的实现,因为它会触发一个无限循环等待端口可用,并且可能会尝试捕获不可恢复的错误,但它应该给您一般的想法。
该实现只有在您使用 0 作为端口值时才真正有用,在这种情况下,它会尝试各种随机端口,直到找到一个可用的端口。
我正在尝试了解如何优雅地使用 scala.util.control.Exception
包。
更具体地说,我想将这段 Java 代码转换为功能方式:
public static boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
我可以在 Scala 中使用 try-catch-finally 做同样的事情,但我正在寻找更实用的方法。另请注意,此 Java 代码使用 try-with-resources
,因此这意味着此代码无论如何都会关闭套接字(即使发生异常):socket.close()
---根据问题澄清进行编辑---
要在 scala 中以函数式风格使用自动资源管理,最简单的方法是使用 scala-arm 然后你可以写
import resource._
def hostAvailabilityCheck():Boolean= {
managed(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).map(_=>true).opt.isDefined
}
如果您真的非常想使用 scala.util.control.Exception
,您可以这样写:
import scala.util.control.Exception._
def hostAvailabilityCheck():Boolean= {
catching[IOException].opt(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)). isDefined
}
return false;
}
更好的是,您可以使用 Try
类型来执行此操作,在这种情况下,您的原始方法将变为:
def hostAvailabilityCheck():Boolean = {
Try(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).isSuccess
}
从你的例子中不清楚你想用这个做什么,但它可能对 return Try
而不是布尔值有用,这样如果端口获取成功后,您不必等待 OS 级别的端口回收,然后再以更明确的方式重新绑定它。
def hostAvailabilityCheck(port: Int):Try[Socket] = {
Try(new Socket(SERVER_ADDRESS, port))
}
然后您的客户端代码可以尝试获取一个端口,直到它真正获得一个:
def acquire(port: Int):Socket={
hostAvailabilityCheck(port).recoverWith(case t:Throwable => acquire(port)).get
}
这是一个幼稚的实现,因为它会触发一个无限循环等待端口可用,并且可能会尝试捕获不可恢复的错误,但它应该给您一般的想法。 该实现只有在您使用 0 作为端口值时才真正有用,在这种情况下,它会尝试各种随机端口,直到找到一个可用的端口。