简体   繁体   English

Java-重新加载类时关闭套接字

[英]Java - Closing socket when reloading class

So I'm working on a server for an IRC, and I added a config screen where you can edit the port it is using, but I have to reintialize the Listen class for it to take effect, so I have this in my Config class: 因此,我正在为IRC的服务器上工作,并添加了一个配置屏幕,您可以在其中编辑它正在使用的端口,但是我必须重新初始化Listen类以使其生效,所以我将它放在Config类中:

Listen.closePorts();
new Listen();

And here is my Listen class: 这是我的Listen课:

package server.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import server.Server;
import server.gui.GUIMain;

public class Listen {
    private static Socket socket = null;
    private int port;

    public Listen() {
        try {
            port = Server.listenPort;
            @SuppressWarnings("resource")
            ServerSocket serverSocket = new ServerSocket(port);
            GUIMain.jta.append("\nServer Started and listening for messages on port " + port + ".\n");

            while(true) {
                socket = serverSocket.accept();
                InputStream is = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String msg = br.readLine();
                GUIMain.jta.append("Received message from client: " + msg + "\n");
            }
        } catch (Exception e) {
            GUIMain.jta.append("Port " + port + " already in use!\n");
        } finally {
            try {
                socket.close();
            }  catch(Exception e) { }
        }
    }

    public static void closePorts() {
        try {
            socket.close();
            GUIMain.jta.append("Server closed\n");
        } catch (IOException e) { }
    }
}

When I start the application it runs this class, opening the socket with the port specified, but when I try to close the port here: 当我启动应用程序时,它将运行此类,并使用指定的端口打开套接字,但是当我尝试在此处关闭端口时:

public static void closePorts() {
    try {
        socket.close();
        GUIMain.jta.append("Server closed\n");
    } catch (IOException e) { }
}

It hangs on socket.close(); 它挂在socket.close();

And if I comment Listen.closePorts(); 如果我评论Listen.closePorts(); out and try to reload the class and leaving the socket open it either hangs or runs the catch() if the port is the same as the port that is in use. 尝试重新加载该类并让套接字保持打开状态,如果该端口与正在使用的端口相同,则该套接字将挂起或运行catch()

So long story short, How can I close the socket before reintalizing the class and use the new port? 简而言之,在重新安装类并使用新端口之前,如何关闭套接字?

Here's the full exception it trows: 这是引发的完整异常:

java.lang.NullPointerException
    at server.network.Listen.closePorts(Listen.java:44)
    at server.gui.GUISettings.actionPerformed(GUISettings.java:86)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

Not providing a direct solution but no exceptions are thrown because your code is swallowing them all. 没有提供直接的解决方案,但是没有抛出异常,因为您的代码吞没了所有异常。 Empty catch blocks are never good practice. 空的捕获块永远不是一个好习惯。 At the very least, print the stack trace of the caught exception using e.printStackTrace() 至少,使用e.printStackTrace()打印捕获到的异常的堆栈跟踪

The socket variable is not assigned until after a client makes a request. 直到客户端发出请求后,才会分配socket变量。 If you call closePorts() before that happens, your program will still be waiting at socket = serverSocket.accept(); 如果在此之前调用closePorts() ,则程序仍将在socket = serverSocket.accept();等待socket = serverSocket.accept(); and socket.close() will throw a NullPointerException because socket will still be null. socket.close()将抛出NullPointerException,因为socket仍为null。

See http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept() for a description of ServerSocket.accept(). 有关ServerSocket.accept()的说明,请参见http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept ()。

There is no class reloading here, and you don't need to close the existing client's accepted sockets. 这里没有重载类,您不需要关闭现有客户端的已接受套接字。 Just close the ServerSocket and recreate it on the new port. 只需关闭ServerSocket并在新端口上重新创建它即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM