Relevant code:
@Test
public void serverTest() throws IOException {
GameServer server = new GameServer();
server.start(9000);
GameClient client1 = new GameClient();
GameClient client2 = new GameClient();
client1.startConnection("localhost", 9000);
client2.startConnection("localhost", 9000);
client1.sendMessage("Hey I am client 1");
client2.sendMessage("Hey I am client 2");
}
public class GameServer {
private ServerSocket serverSocket;
public void start(int port) throws IOException {
System.out.println("Server started !!!");
serverSocket = new ServerSocket(port);
while (true) {
new Thread(new GameClientHandler(serverSocket.accept())).start();
}
}
public void stop() throws IOException {
serverSocket.close();
}
private static class GameClientHandler implements Runnable {
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public GameClientHandler(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
try {
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine = in.readLine();
while ((inputLine = in.readLine()) != null){
System.out.print(inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
out.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Why can't the server and client be started together in the @Test
? I think it gets stuck in the infinite while loop but at the same time, shouldn't there be context switching with the new threads started after accepting the connection?
I expected at least the name of the 2 new threads to be printed but it doesn't happen.
CodePudding user response:
Let us look carefully to your test code:
GameServer server = new GameServer();
Ok, this lines creates a server, and the test thread is ready to execute next line
server.start(9000);
Ok, the test thread starts the server, and will be ready to execute the next line when the start
method will return.
What happens in start
:
System.out.println("Server started !!!");
Ok, you should see that message
serverSocket = new ServerSocket(port);
Ok, you have created a ServerSocket
while (true) {
new Thread(new GameClientHandler(serverSocket.accept())).start();
}
ok you a waiting for a connection (at serverSocket.accept()
), will create a new thread to handle it as soon as you will get one, and loop again.
But as this point, the test thread is waiting and will never go to the following line to start the first connection. And it will remain stuck unless something else (maybe another thread) starts those damned connections.
CodePudding user response:
The method GameServer.start
will only return with an exception. That is because you have the while-loop.
So your test execution will start the server and wait for someone to open a connection, but that never happens.