I am building a multithread chat server.
The multi-threaded server (Manager Class) could serve many clients. It receives a message from a client, and broadcast to all clients.
The client (Peer Class) have two threads - SendThread for sending a message to the server. ReceiveThread to listen to the server broadcast.
However, while running the client program, it catches the exception and says that socket closed.
My code for the server class is below:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Manager {
public int port;
public ArrayList<Socket> clients;
public Manager(int port) throws IOException {
this.port = port;
this.clients = new ArrayList<>();
try (ServerSocket server = new ServerSocket(port)){
System.out.println("Waiting for client connection-");
while (true){
Socket client = server.accept();
clients.add(client);
System.out.println("Client applies for connection");
Thread t = new Thread(new serverClientThread(client));
t.start();
}
}
}
public class serverClientThread implements Runnable {
private Socket client;
public serverClientThread(Socket client){
this.client = client;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(this.client.getInputStream()));
while (true){
// read
String line = reader.readLine();
if (line != null){
System.out.println("I received "+line);
// write
// broadcast
broadcast("I received " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// broadcast the message to all clients
public synchronized void broadcast(String message) throws IOException {
for (Socket client:this.clients){
if (client.isClosed()){
continue;
}
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))){
writer.write("I received " + message);
writer.newLine();
writer.flush();
}
}
}
}
The code of the client class is below:
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Peer {
public String hostname;
public int port;
public Peer(String hostname, int port){
this.hostname = hostname;
this.port = port;
try (Socket socket = new Socket(hostname, port)){
// create writer
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Thread t1 = new Thread(new SendThread(writer));
Thread t2 = new Thread(new ReceiveThread(reader));
t1.start();
t2.start();
} catch (UnknownHostException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
public class SendThread implements Runnable{
private BufferedWriter writer;
public SendThread(BufferedWriter writer){
this.writer = writer;
}
@Override
public void run() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("Enter a String: ");
String str = sc.nextLine();
// send to server
if (str != null){
try {
this.writer.write(str);
this.writer.newLine();
this.writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class ReceiveThread implements Runnable{
private BufferedReader reader;
public ReceiveThread(BufferedReader reader){
this.reader = reader;
}
@Override
public void run() {
while (true){
String res = null;
try {
res = this.reader.readLine();
if (res != null){
System.out.println("Server response: "+ res);
}
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
}
}
The error message is:
java.net.SocketException: Socket closed
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at Peer$ReceiveThread.run(Peer.java:86)
at java.base/java.lang.Thread.run(Thread.java:834)
It occurs in ReceiveThread in the Peer class.
Any bits of help is appreciated. Thank you!
Yige