>我正在尝试编写一个函数来使用新端口重新启动我的ServerSocket。新端口由用户通过面板(该部分代码是正确的)提供,其中 restart() 函数被收集。新端口将保存到静态字段端口数字字符串。
以下是我尝试重新启动服务器的代码。重新启动的服务器不工作。原始端口工作正常。
public static void main(String [] args) throws IOException, ClassNotFoundException
{
runServer(false);
}
public static void runServer(boolean changePort)
{
try
{
ServerSocket socket = new ServerSocket(Integer.parseInt(portNumString));
Server server = new Server(socket);
while(!changePort)
{
server.accept();
if(changePort && socket!=null)
{
socket.close();
runServer(false);
}
}
}
catch(Exception e)
{
System.out.println("EXCEPTION !!! "+e);
}
}
public static void restart() throws NumberFormatException, ClassNotFoundException, IOException
{
System.out.println("Restart Called... ");
runServer(true);
}
编辑:
调用 restart() 的代码部分
cloesButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
portNumString=txtPort.getText();
try
{
restart();
}
catch(NumberFormatException e1)
{
e1.printStackTrace();
}
}
});
我假设restart()
是从另一个线程调用的,因为runServer
方法有一个永不终止的循环(因为changePort
是一个本地参数,循环内没有任何变化)
restart()
不会停止现有的服务器。
它只是再次通过该方法 开始一个新的ServerSocket
,旧的仍在运行。
由于布尔changePort
为 true,它甚至不会进入 while
循环,并且从不接受客户端套接字。另一方面,旧的服务器套接字仍在愉快地运行。
为了使它正常工作,您需要使用适当的类,而不是一堆static
方法。将端口号和serverSocket
等内容作为成员变量。然后在 while 循环中检查这些内容,而无需再次调用该方法。像这样:
while (true) {
this.serverSocket = new ServerSocket(this.portNum);
try {
Socket client = server.accept();
//todo: do something with the client
}
catch (IOException ex) {
//an IO error occurred, probably we were asked to restart
}
}
然后你可以有这样的东西:
void restart(int portNum) {
this.portNum = portNum;
try {
this.serverSocket.close();
} catch (IOException ex) {
//todo: handle it or log it somewhere
}
}