3

我想将InputStream包含 XML 从客户端发送到服务器。所述服务器使用 XML 流操作Streaming API for XML (StAX)并将其发送回客户端。

我设法将 XML 发送到服务器,客户端收到答案,但没有退出,因为服务器从未完成读取InputStream客户端的表单。但是当服务器只是将输入转储System.out而不是发送某些东西时,读取完成......

编辑我忘了提到它IOUtils.copy()在客户端上的两个单独的线程中运行。

这里有一些代码可以重现这一点,我已经在服务器上替换了该StAX部分。IOUtils.copy()

服务器

ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();

InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
IOUtils.copy(in, out);

客户

Socket socket = new Socket(host, port);
FileInputStream fin = new FileInputStream(file);
OutputStream out = socket.getOutputStream();
IOUtils.copy(fin, out)

InputStream in = socket.getInputStream();
IOUtils.copy(in, System.out)
4

3 回答 3

5

您必须刷新并关闭 InputStream 和 OutputStream。像这样:

ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();

InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
IOUtils.copy(in, out);

//add 
out.flush();
in.close();
out.close;
于 2013-02-17T08:15:55.530 回答
3

您可能正在创建死锁。

  • 客户端 - 向服务器发送数据。
  • 服务器 - 将数据循环回客户端。
  • 客户端 - 读取数据(服务器环回)

因此,当客户端向服务器发送数据时,服务器正在将其发送回客户端。客户端没有读取该数据,它正忙于发送。

在某些时候,TCP 缓冲区会填满,服务器会阻止向客户端发送更多数据。这意味着服务器在发送数据时被阻塞,因此最终服务器接收端的 TCP 缓冲区也被填满,客户端在发送数据时被阻塞。由于客户端现在在发送时被阻塞,它永远不会到达它读取环回数据的部分,因此服务器永远不会解除阻塞。

如果您正在发送一个小文档,您可能不会遇到这种情况,因为所有数据都适合缓冲区,但是一旦您填满缓冲区,系统就会死锁。

您必须复用发送/接收。例如,您可以在客户端上启动一个线程

InputStream in = socket.getInputStream();
IOUtils.copy(in, System.out)

这样接收可以与客户端发送数据并行完成

或者您可以在服务器端使用 2 个线程。一个用于接收数据,将数据发送回另一个执行发送的线程(在这种情况下,您必须在线程之间建立一个内部队列)。

于 2010-12-01T15:03:38.877 回答
1

据我记得IOUtils.copy()不刷新也不关闭流。似乎您也没有调用既不刷新也不关闭。试试看。我相信这是你的问题。

于 2010-12-01T15:24:32.043 回答