我正在尝试编写一个函数以使用新端口重新启动ServerSocket。用户通过面板(该部分代码正确)提供了新端口,在该面板中对restart()函数进行了整理。新端口将保存到静态字段portNumString。
以下是我尝试重新启动服务器的代码。重新启动的服务器无法正常工作。原始端口正常工作。
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();
}
}
});
答案 0 :(得分:2)
我假设正在从另一个线程调用restart()
,因为runServer
方法具有一个永不终止的循环(因为changePort
是局部参数,并且在循环内没有任何改变) )
restart()
未停止现有服务器。
它只是通过新方法重新启动新 ServerSocket
,而旧方法仍在运行。
由于布尔值changePort
为真,因此它甚至不会进入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
}
}