Reputation: 69
I'm trying to create a server in java which accepts clients. Currently, two clients can connect to the server. However, when one leaves the other client can no longer communicate with the server. I think the issue is that my clientSocket is created outside my thread, which means it must be declared as 'final' because I use an innerclass. However, if I move it into the thread it cannot create the clientSocket. Any ideas on how to fix this? Thanks in advance.
Comment: If I close the clientSocket when the client leaves it says "Broken Pipe" error because the clientSocket is final so it cannot be changed - ie the clientSocket is the same for both clients.
private BufferedWriter writer;
private LODGame game;
public Server(int port) throws Exception {
try{
// Listen on the given port.
serverSocket = new ServerSocket(port);
game = new LODGame();
}
catch(BindException e){
throw new Exception("Failed to create a server socket: "+
e.getMessage());
}
}
public Server(int port, String map) throws Exception {
try{
// Listen on the given port.
serverSocket = new ServerSocket(port);
game = new LODGame(map);
}
catch(BindException e){
throw new Exception("Failed to create a server socket: "+
e.getMessage());
}
}
public void run() throws Exception {
final ServerSocket serverSocket = getServerSocket();
while (true){
System.out.println("Listening for a client on port: "+
serverSocket.getLocalPort());
// Wait for a client to make contact.
final Socket clientSocket = serverSocket.accept();
// Contact ...
System.out.println("A client has arrived.");
Thread serverThread = new Thread(){
public void run(){
boolean quit = false;
while (!quit){
try{
// Wrap the input stream in a BufferedReader.
BufferedReader reader = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
// Wrap the output stream in a BufferedWriter.
writer = new BufferedWriter(
new OutputStreamWriter(clientSocket.getOutputStream()));
game.setWriter(writer);
game.startNewGame();
// Read lines until the client terminates.
String request = reader.readLine();
while(request != null){
// Write the length of the line as a String.
playerCommand(request);
request = reader.readLine();
}
}
catch(IOException e){
System.out.println("IOException talking to the client: "+
e.getMessage());
}
finally{
if(clientSocket != null){
System.out.println("The client has gone.");
break;
// Close the socket to the client.
//try
// {
// clientSocket.close();
// }
//catch(Exception e)
// {
// System.out.println("Error" + e.getMessage());
// System.exit(1);
// }
}
}
try
{
serverSocket.close();
}
catch(Exception e)
{
System.out.println("Error" + e.getMessage());
System.exit(1);
}
}
}
};
serverThread.start();
}
}
protected ServerSocket getServerSocket(){
return serverSocket;
}
// The socket on which the listening is done.
private final ServerSocket serverSocket;
Upvotes: 2
Views: 1429
Reputation: 116888
No this has nothing to do with the clientSocket
being final
. Your problem is that you are closing the serverSocket
in the client thread. You should be closing the clientSocket only at the end of the thread:
while (!quit) {
try {
...
} catch(IOException e){
System.out.println("IOException talking to the client: "+
e.getMessage());
} finally {
...
clientSocket.close();
}
// DON'T DO THIS: serverSocket.close();
}
The serverSocket
should only be closed if accept()
throws an Exception
-- it should not be touched by the client thread at all.
Upvotes: 3