Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
66 views
in Technique[技术] by (71.8m points)

Chatting App: Java Socket Unexpectedly Closing

I am having a problem with my chatting application built using java sockets. Everything works fine until a client receives a message. After the message is received and printed to the terminal the socket which received the message closes (not the one which sent).

The server prints the error message:

Listening for connections on port 65432...
Client connected: </127.0.0.1>
Client thread started
Client connected: </127.0.0.1>
Client thread started
</127.0.0.1> hello
Sent message to client </127.0.0.1>
Failed to run client thread for </127.0.0.1>. Closing connection...
null
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 chat_v4.ClientHandler.run(Server.java:77)

Which doesn't really help find why it closes because it just points to the input.readline().

The client prints no error message to the terminal when this happens it just disconnects.

Client:

package chat_v4;

import java.net.*;
import java.util.*;
import java.io.*;

public class Client {
    public static void main(String[ ] args) throws IOException {
        try {
            Socket s = new Socket("localhost", 65432);
            Scanner usrIn = new Scanner(System.in);
            System.out.println("Connected to server.");
            ClientThread t = new ClientThread(s);
            t.start();
            
            PrintWriter output = new PrintWriter(s.getOutputStream(), true);
            String sending;
            
            while (true) {
                sending = usrIn.nextLine();
                if (sending != null) {
                    if (sending.equals("q") || sending.equals("exit")) {
                        output.println(sending);
                        break;
                    }
                    else {
                        output.println(sending);
                    }
                }
            }
            s.close();
            usrIn.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class ClientThread extends Thread {
    Socket s;
    
    public ClientThread(Socket s) {
        this.s = s;
    }

    public void run() {
        try {
            BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String message;
            
            while (true) {
                message = input.readLine();
                if (message != null) {
                    System.out.println(message);
                }
            }
        }
        catch (Exception e) {
            System.out.println("Failed to start message thread. Closing connection...");
            e.printStackTrace();
            try {
                s.close();
            }
            catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}

Server:

package chat_v4;

import java.util.*;
import java.net.*;
import java.io.*;

public class Server {
    public static List<Socket> threads = new ArrayList<Socket>();
    
    public static void main(String[ ] args) throws IOException {
        Socket s;
        
        try (ServerSocket ss = new ServerSocket(65432);) {
            System.out.println("Listening for connections on port 65432...");
            while (true) {
                try {
                    s = ss.accept();
                    String addr = "<" + s.getInetAddress() + ">";
                    System.out.println("Client connected: " + addr);
                    ClientHandler t = new ClientHandler(s, addr);
                    threads.add(s);
                    t.start();
                }
                catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            System.out.println("Program finished");
        }
    }
    
    public static void remove(Socket socket) {
        threads.remove(socket);
    }
    
    public static void broadcast(String message, Socket socket) {
        for (Socket client : threads) {
            if (client != socket) {
                try {
                    PrintWriter output = new PrintWriter(client.getOutputStream(), true);
                    output.println(message);
                    System.out.println("Sent message to client " + "<" + client.getInetAddress() + ">");
                    output.close();
                }
                catch (Exception e) {
                    System.out.println("Failed to send message to client " + "<" + client.getInetAddress() + ">");
                    e.printStackTrace();
                }
            }
        }
    }
}

class ClientHandler extends Thread {
    final Socket s;
    final String addr;
    
    public ClientHandler(Socket s, String addr) {
        this.s = s;
        this.addr = addr;
    }
    
    @Override
    public void run() {
        try {
            System.out.println("Client thread started");
            
            BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String received;
            
            while (true) {
                received = input.readLine();
                
                if (received.equalsIgnoreCase("q") || received.equalsIgnoreCase("exit")) {
                    System.out.println("Client " + addr + " closed connection with server.");
                    Server.remove(s);
                    s.close();
                    break;
                }
                else {
                    System.out.println(addr + " " + received);
                    Server.broadcast(received, s);
                    received = null;    
                }
            }
        } 
        catch (Exception e) {
            System.out.println("Failed to run client thread for " + addr + ". Closing connection...");
            System.out.println(e.getCause());
            e.printStackTrace();
            try {
                Server.remove(s);
                s.close();
            }
            catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}

I've been struggling with this problem for days now and any help would be appreciated.

(Also, a lot of the code is useless snippets from my attempts at finding out why this problem occurs)

question from:https://stackoverflow.com/questions/65838637/chatting-app-java-socket-unexpectedly-closing

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...