Shantanu Shinde
Shantanu Shinde

Reputation: 1012

Java IOException Stream Closed in Server Client program

I am trying to make a Server Client program that allows sending multiple messages from server to client or vice versa without waiting for a response. The program works fine when the first client is connected and disconnected. But when I connect the client again, I get the error. Here is my server code:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

import java.io.InputStreamReader;

import java.io.BufferedReader;

class Q2Server implements Runnable{
    private ServerSocket serverSocket;
    private Socket socket;
    private DataOutputStream out;
    private BufferedReader in1;
    private DataInputStream in2;
    private Thread read, write;
    private String clientMsg, serverMsg;

    public Q2Server (int port) throws IOException{
        serverSocket = new ServerSocket(port);

        while(true) {
            try {
                System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
                socket = serverSocket.accept();

                System.out.println("Just connected to " + socket.getRemoteSocketAddress());

                out = new DataOutputStream(socket.getOutputStream());
                out.writeUTF("Thanks for connecting to " + socket.getLocalSocketAddress());

                clientMsg = "";
                serverMsg = "";

                read = new Thread(this);
                write = new Thread(this);

                read.start();
                write.start();

                read.join();
                write.join();

            } catch(IOException e) {
                e.printStackTrace();
            } catch(InterruptedException ie) {
                ie.printStackTrace();
            }
        }

    }

    public void run () {
        try {
            if(Thread.currentThread() == write) {
                while(true) {
                    try {
                        if(clientMsg.equals("close")) {
                            break;
                        } else {
                            in1 = new BufferedReader(new InputStreamReader(System.in));
                            out = new DataOutputStream(socket.getOutputStream());
                            serverMsg = in1.readLine();
                            out.writeUTF(serverMsg);
                            if(serverMsg.equals("close")) {
                                socket.close();
                                in1.close();
                                in2.close();
                                out.close();
                                System.out.println("Closing connection...");
                                break;
                            }    
                        }
                    } catch (SocketException s) {
                        break;
                    } 

                } 

            } else {
                while(true) {
                    try {
                        if(serverMsg.equals("close")) {
                            break;
                        }
                        in2 = new DataInputStream(socket.getInputStream());
                        clientMsg = in2.readUTF();
                        System.out.println("Client: " + clientMsg);
                        if(clientMsg.equals("close")) {
                            socket.close();
                            in1.close();
                            in2.close();
                            out.close();
                            System.out.println("Closing connection...");
                            break;
                        }
                    } catch(SocketException s) {
                        break;
                    } 

                } 

            }
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
    public static void main(String[] args) throws IOException {
        Q2Server server = new Q2Server(8080);
    }
}

Client code:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.rmi.UnexpectedException;


import java.io.InputStreamReader;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.lang.Thread;

class Q2Client implements Runnable {
    private Socket socket;
    private Thread read, write;
    private BufferedReader in1;
    private DataInputStream in2;
    private DataOutputStream out;
    private String clientMsg, serverMsg;

    public Q2Client(int port) {
        try {
            socket = new Socket("localHost",port);
            System.out.println("Connected to port: " + port);

            clientMsg = serverMsg = "";

            read = new Thread(this);
            write = new Thread(this);

            in2 = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

            System.out.println(in2.readUTF());

            read.start();
            write.start();

            read.join();
            write.join();

        } catch(UnexpectedException u) {
            u.printStackTrace();
        } catch(IOException i) {
            i.printStackTrace();
        } catch(InterruptedException ie) {
            ie.printStackTrace();
        }
    }

    public void run() {
        try {
            if(Thread.currentThread() == write) {
                while(true) {
                    try {
                        if(serverMsg.equals("close")) {
                            break;
                        }
                        in1 = new BufferedReader(new InputStreamReader(System.in));
                        out = new DataOutputStream(socket.getOutputStream());
                        clientMsg = in1.readLine();
                        out.writeUTF(clientMsg);
                        if(clientMsg.equals("close")) {
                            socket.close();
                            in1.close();
                            in2.close();
                            out.close();
                            System.out.println("Closing connection...");
                            break;
                        }
                    } catch (SocketException s) {
                        break;
                    } 

                } 
            } else {
                while(true) {
                    try {
                        if(clientMsg.equals("close")) {
                            break;
                        }
                        in2 = new DataInputStream(socket.getInputStream());
                        serverMsg = in2.readUTF();
                        System.out.println("Server: " + serverMsg);
                        if(serverMsg.equals("close")) {
                            socket.close();
                            in1.close();
                            in2.close();
                            out.close();
                            System.out.println("Closing connection...");
                            break;
                        }
                    } catch (SocketException s) {
                        break;
                    }

                } 
            }
        } catch (IOException i) {
            i.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Q2Client client = new Q2Client(8080);
    }
}

Here is the stacktrace of the exception:

java.io.IOException: Stream closed at java.base/java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:176) at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:342) 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 Q2Server.run(Q2Server.java:65) at java.base/java.lang.Thread.run(Thread.java:835)

When either of the server or client sends "close" the connection closes. The client can connect again. But when I run the client code again, I get the exception. What is going wrong and how do I fix this?

Upvotes: 0

Views: 3399

Answers (1)

Woon Flivver
Woon Flivver

Reputation: 56

You're getting an exception because you're trying to read from a BufferedReader which no longer exists, the in1 in particular. At the first run, all your streams and readers open as they should, but after getting the command close from the client, your server closes the in1. Then, when the client tries to reconnect, the program tries to assign the value of in1.readLine() to serverMsg which is a String, but since in1 is no more, the IOException occurs since the BufferedReader is closed and nothing can be read from it.

I suppose since you want to leave the server running while the client(s) can connect and disconnect at any given time, which totally makes sense, maybe you shouldn't close the BufferedReader which supplies keyboard commands to the server in your case. Closing it doesn't make sense to me, since you're not stopping the whole server when the client disconnects, you just close the connection, but the server still should be able to accept commands.

Hope this helps.

Upvotes: 3

Related Questions