Bob
Bob

Reputation: 10795

multithreaded TCP server: java.net.SocketException: Socket closed

My code is as follows. When request comes, server creates two threads (producer-consumer pattern):

...
while(true) {
    Socket clientSocket = server.accept();
    System.out.println("Got connection!");

    Thread consumerThread = new Thread(new ConsumerThread(sharedQueue, clientSocket));
    Thread producerThread = new Thread(new ProducerThread(sharedQueue, clientSocket));

    consumerThread.start();
    producerThread.start();
}
...

Consumer thread reads what client sent and producer thread responds back. Consumer:

@Override
    public void run() {
        try {
            while (true) {
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                // read, do actions
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

Producer:

 @Override
    public void run() {
        try {
            out = new PrintStream(clientSocket.getOutputStream(), true);
            // some actions
            out.println("something");

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

But in server I get following error:

java.net.SocketException: Socket closed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)
    at java.net.SocketInputStream.read(SocketInputStream.java:121)
    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 ee.ut.ds.server.ConsumerThread.run(ConsumerThread.java:30)
    at java.lang.Thread.run(Thread.java:745)

What might cause this? I even see that client accepts message correctly. Also, in producer thread I close a socket. I do not understand.

Upvotes: 1

Views: 11992

Answers (3)

user207421
user207421

Reputation: 310859

You closed the socket and continued to use it.

Don't close the socket, or its output stream, until you have read end of stream from the BufferedReader.

Construct the BufferedReader outside the loop.

You probably don't need two threads per socket.

Upvotes: 5

Ponmani Palanisamy
Ponmani Palanisamy

Reputation: 78

The problem is because you are closing the socket from your produce after writing something to it. If you want the socket to be open, just close the output stream in the finally block in Producer. You can close the socket from Server/Producer/Consumer once you are sure that there is no more network I/O to happen over the socket.

https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#close()

Upvotes: -1

Shriram
Shriram

Reputation: 4411

You are starting both the threads in parallel. You can't predict the behvaiour of threads. You are using the same socket for both the threads and if producer thread starts you are closing socket in finally section. you should not close the connection and make sure the race condition should not occur.

Upvotes: -1

Related Questions