Eri*_*ans 10 java serversocket
我有这个该死的结构:
public void run() {
try {
if (!portField.getText().equals("")) {
String p = portField.getText();
CharSequence numbers = "0123456789";
btnRun.setEnabled(false);
if (p.contains(numbers)) {
ServerSocket listener = new ServerSocket(Integer.parseInt(p));
while (true) {
Socket socket = listener.accept();
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hi there, human.");
} finally {
socket.close();
}
}} else {
JOptionPane.showMessageDialog(null, "Only numbers are allowed.");
}
}
} catch (NumberFormatException | HeadlessException | IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我需要完全像使用套接字一样关闭侦听器.问题是,如果我在循环后尝试这样做,代码将"无法访问",如果我尝试在ServerSocket的任何地方声明一个字段,我会得到一个NullPointerException.我不想与socket/client一起关闭ServerSocket,因为我想建立新的连接.
这是我的问题:
在这种情况下关闭ServerSocket真的是必要的吗?当软件关闭时,ServerSocket会自行关闭?(System.exit(0)).如果我关闭软件时继续运行ServerSocket只是因为我没有关闭它,那么我有一个问题,因为我无法达到那个血腥的代码来关闭它:).
ζ--*_*ζ-- 11
是.虽然销毁对套接字的引用可能导致垃圾收集器完成它,但是没有指定它将被关闭.这在许多情况下是特定于实现的,并且由于性能或甚至难以跟踪的微小错误,有时可能相对于设计脱轨.
保持任何地方的参考是一个肯定的赌注,即使有WeakReferences也不会.
现在,OS可以提供有限的(由于它的设计)插座数量.当您打开越来越多的套接字时,操作系统会受到压力并最终耗尽套接字,导致Java或其他程序失败.此外,根据您或默认设置可能设置的套接字选项,此套接字可能会发送keepalive,也会耗尽其他端点上的资源.
退出时,套接字在其构造函数中注册关闭操作以关闭它,和/或操作系统的自动清理,从而关闭它.
您永远不应该依赖OS/JVM行为或完成来关闭套接字,尤其是如果您有多个套接字,即使您不打算同时使用所有套接字也是如此.
是的,有必要释放任何有限的资源,否则你的应用程序会让主机上的其他进程饿死资源,并且无法长期维持
这是我如何做这样的任务:
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = ... // init here
} catch (...) {
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// log error just in case
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,将GUI代码移动到其他类是一个不错的主意,以保持清洁.