ServerSocket 不会等到关闭后再打开
ServerSocket wont wait until it's closed to reopen
我正在 java 中编写一个 client/server 应用程序,我试图让服务器能够自行重启。当前,服务器接受连接,从客户端读取对象,然后将 Object/Socket/Stream 传递给从那里接管的新线程。下一部分是问题所在:要重新启动已经 运行ning 服务器(我们称此实例为 "instance 1"),我启动了它的一个新实例(实例 2)。如果 ServerSocket 已经在使用中,实例 2 应该向 ServerSocket 写入一个空值,这将导致实例 1 关闭它,然后实例 2 应该只是 运行 与以前相同的块。这样做成功地终止了实例 1,但除非我进入调试模式并控制哪一行发生,否则实例 2 会在关闭之前尝试重新打开 ServerSocket,因此它也会终止。我无法让实例 2 等到 ServerSocket 关闭后再尝试打开它。有没有我找不到的方法或实现?
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Tester {
protected ExecutorService threadPool = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
new Tester();
}
public Tester () {
try {
listen();
} catch (Exception e) {
try {
Socket socket = new Socket("127.0.0.1", 4444);
new ObjectOutputStream(socket.getOutputStream()).writeObject(null);
socket.close();
listen();
} catch (Exception ex) { e.printStackTrace(); }
}
return;
}
public void listen () throws Exception {
try (ServerSocket serverSocket = new ServerSocket(4444);) {
while (true) {
Socket clientSocket = serverSocket.accept();
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
Object obj = in.readObject();
if(obj == null)
break;
// this.threadPool.execute(new ServerThread( ... ));
}
threadPool.shutdown();
} catch (Exception e) {
e.printStackTrace();
throw new Exception();
}
}
}
尝试在延时循环中打开 ServerSocket,例如
for (int i = 0; i < 3; i++) {
Thread.sleep(2000); //select your sleep time
try {
reopenMyServerSocket();
break;
}
catch (IOException iox) {}
}
使用线程将是处理此问题的合适方法。如果你想使用线程,那么你可以按照我的例子。
public static void main(String[] args) {
renderServer(9000);//render socket and handle request
}
public static void renderServer(int port){
ServerSocket serverSocket = new ServerSocket (port);
System.out.println("Server started on "+ new Date());
while(true){
Socket socket = serverSocket.accept();
HandleClient handleClient = new HandleClient(socket);
Thread thread = new Thread(handleClient);
thread.start();
}
}
然后您必须创建 HandleClient class 来处理每个请求。请注意 HandleClient class 必须实现 Runnable,如下例所示。
public class HandleClient implements Runnable{
Socket socket;
public HandleClient(Socket socket){
this.socket = socket;
}
@Override
public void run() {
//Your code goes in here
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
//Then you can continue from here
}
}
我正在 java 中编写一个 client/server 应用程序,我试图让服务器能够自行重启。当前,服务器接受连接,从客户端读取对象,然后将 Object/Socket/Stream 传递给从那里接管的新线程。下一部分是问题所在:要重新启动已经 运行ning 服务器(我们称此实例为 "instance 1"),我启动了它的一个新实例(实例 2)。如果 ServerSocket 已经在使用中,实例 2 应该向 ServerSocket 写入一个空值,这将导致实例 1 关闭它,然后实例 2 应该只是 运行 与以前相同的块。这样做成功地终止了实例 1,但除非我进入调试模式并控制哪一行发生,否则实例 2 会在关闭之前尝试重新打开 ServerSocket,因此它也会终止。我无法让实例 2 等到 ServerSocket 关闭后再尝试打开它。有没有我找不到的方法或实现?
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Tester {
protected ExecutorService threadPool = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
new Tester();
}
public Tester () {
try {
listen();
} catch (Exception e) {
try {
Socket socket = new Socket("127.0.0.1", 4444);
new ObjectOutputStream(socket.getOutputStream()).writeObject(null);
socket.close();
listen();
} catch (Exception ex) { e.printStackTrace(); }
}
return;
}
public void listen () throws Exception {
try (ServerSocket serverSocket = new ServerSocket(4444);) {
while (true) {
Socket clientSocket = serverSocket.accept();
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
Object obj = in.readObject();
if(obj == null)
break;
// this.threadPool.execute(new ServerThread( ... ));
}
threadPool.shutdown();
} catch (Exception e) {
e.printStackTrace();
throw new Exception();
}
}
}
尝试在延时循环中打开 ServerSocket,例如
for (int i = 0; i < 3; i++) {
Thread.sleep(2000); //select your sleep time
try {
reopenMyServerSocket();
break;
}
catch (IOException iox) {}
}
使用线程将是处理此问题的合适方法。如果你想使用线程,那么你可以按照我的例子。
public static void main(String[] args) {
renderServer(9000);//render socket and handle request
}
public static void renderServer(int port){
ServerSocket serverSocket = new ServerSocket (port);
System.out.println("Server started on "+ new Date());
while(true){
Socket socket = serverSocket.accept();
HandleClient handleClient = new HandleClient(socket);
Thread thread = new Thread(handleClient);
thread.start();
}
}
然后您必须创建 HandleClient class 来处理每个请求。请注意 HandleClient class 必须实现 Runnable,如下例所示。
public class HandleClient implements Runnable{
Socket socket;
public HandleClient(Socket socket){
this.socket = socket;
}
@Override
public void run() {
//Your code goes in here
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
//Then you can continue from here
}
}