我的代码如下。当请求到来时,服务器创建两个线程(生产者 - 消费者模式):
...
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线程读取客户端发送的内容和生产者线程的响应。消费者:
@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();
}
}
}
制片:
@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();
}
}
但在服务器中我收到以下错误:
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)
可能是什么原因引起的?我甚至看到客户端正确接受消息。另外,在生产者线程中我关闭了一个套接字。我不明白。
答案 0 :(得分:5)
您已关闭套接字并继续使用它。
在您阅读BufferedReader.
在循环外构建BufferedReader
。
每个插槽可能不需要两个线程。
答案 1 :(得分:-1)
您正在并行启动两个线程。你无法预测线程的多样性。您正在为两个线程使用相同的套接字,如果生成器线程启动,则在最后一节中关闭套接字。 你不应该关闭连接,并确保不会发生竞争条件。
答案 2 :(得分:-1)
问题是因为你在写完东西之后就从你的产品中关闭了套接字。 如果要打开套接字,只需关闭Producer中finally块中的输出流。 一旦确定通过套接字不再发生网络I / O,就可以从Server / Producer / Consumer关闭套接字。
https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#close()