Reputation: 10795
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
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
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
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