I am trying to create a multi-threaded duplex chat server. I had it working fine before I moved the code into threads, but now I'm getting "SocketException: Socket is closed" whenever a thread tries to access a socket.
My teacher and I can't figure it out. (teacher knows even less Java than I do; he is a C guy). It seems like the socket is open, but as soon as it goes into the thread, it is closed.
What am I doing wrong?
Client code:
public class Client {
public static void main(String[] args) throws IOException {
String hostName = "localhost";
int portNumber = 6969;
try (
Socket socket = new Socket(hostName, portNumber);
) {
System.out.println("Chat connected");
//Sender
if (!socket.isClosed())
new Thread(new Sender(socket)).start();
//Receiver
if (!socket.isClosed())
new Thread(new Receiver(socket)).start();
} catch (SocketException e) {
System.out.println("Connection terminated unexpectedly");
}
}
}
Server code:
public class Server {
public static void main(String[] args) throws IOException {
int portNumber = 6969;
try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
) {
//Receiver
if (!clientSocket.isClosed())
new Thread(new Receiver(clientSocket)).start();
//Sender
if (!clientSocket.isClosed())
new Thread(new Sender(clientSocket)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Receiver thread code:
class Receiver implements Runnable {
private Socket socket;
Receiver(Socket s) throws IOException {
socket = s;
}
@Override
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String received;
do {
received = in.readLine();
if (received == null) break;
System.out.println("Them: " + received);
} while (!received.contains("/dropmic"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sender thread code:
class Sender implements Runnable {
private Socket socket;
Sender(Socket s) throws IOException {
socket = s;
}
@Override
public void run() {
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {
String sent;
do {
System.out.print("You: ");
sent = stdIn.readLine();
if (sent == null) break;
out.println(sent);
} while (!sent.contains("/dropmic"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server output:
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:943)
at Sender.run(Sender.java:16)
at java.lang.Thread.run(Thread.java:745)
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at Receiver.run(Receiver.java:19)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
Client output (Still running):
Chat connected
You: java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:903)
at Receiver.run(Receiver.java:16)
at java.lang.Thread.run(Thread.java:745)
You are using a try-with-resources statement, and putting the socket as the resources. However, when you create the new thread, this try-with-resources reaches the end of its code and closes the sockets. Put your sockets inside the actual try statement and close them manually to fix this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With