使用 IOUtils.copy() 时套接字流挂起
我想将包含 XML 的 InputStream
从客户端发送到服务器。所述服务器使用Streaming API for XML (StAX)
操作XML流并将其发送回客户端。
我设法将 XML 发送到服务器,客户端收到答案,但不会退出,因为服务器永远不会完成从客户端读取 InputStream
。 但是,当服务器只是将输入转储到 System.out 而不是发送某些内容时,读取就完成了...
编辑我忘了提及这一点IOUtils.copy()
在客户端上的两个单独线程中运行。
这里有一些代码可以重现这一点,我在服务器上用 IOUtils.copy()
替换了 StAX
部分。
服务器
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)
I want to send an InputStream
containing XML from the client to a server. Said server manipulates the XML stream using Streaming API for XML (StAX)
and sends it back to the client.
I mange to send the XML to the server, the client receives the answer, but doesn't exit because the server never finishes reading the InputStream
form the client.
But when the server is just dumping the input to System.out
instead of sending something, reading finishes...
edit I forgot to mention that IOUtils.copy()
is running in two separate threads on the client.
Here some code to reproduce this, I've replaced the StAX
part with IOUtils.copy()
on the server.
Server
ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();
InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
IOUtils.copy(in, out);
Client
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须刷新并关闭InputStream 和OutputStream。
像这样:
You must flush and close InputStream and OutputStream.
like this:
您可能正在造成僵局。
因此,当客户端将数据发送到服务器时,服务器将其发送回客户端。
客户端没有读取该数据,而是正忙于发送。
在某些时候,TCP 缓冲区会填满,服务器会阻止向客户端发送更多数据。这意味着服务器在发送数据时被阻止,因此最终服务器接收端的 TCP 缓冲区也被填满,并且客户端在发送数据时被阻止。由于客户端现在在发送时被阻止,因此它永远不会到达读取环回数据的部分,因此服务器永远不会解除阻止。
如果您发送一个小文档,您可能不会遇到这种情况,因为所有数据都适合缓冲区,但是一旦填满缓冲区,系统就会死锁。
您必须复用发送/接收。例如,您可以在客户端上启动一个线程,
这样接收数据可以与客户端发送数据并行完成
,或者您可以在服务器端使用 2 个线程。一个用于接收数据,将要发送回的数据发送回另一个执行发送的线程(在这种情况下,您必须在线程之间建立一个内部队列)。
You are probably creating a deadlock.
So, while the client is sending data to the server, the server is sending it back to the client.
The client isn't reading that data, it's busy sending.
At some point the TCP buffers fill up, and the server blocks on sending more data to the client. This means the server is blocked on sending data, so eventually the TCP buffers on the receiving side of the server fills up as well, and the client blocks on sending data. Since the client is now blocked on sending, it'll never get to the part where it reads the data that is looped back, so the server will never un-block.
If you're sending a small document, you might not experience this, as all the data fits in the buffers, but once you fill up the buffers, the system will deadlock.
You have to multiplex the sending/receiving. e.g. you could start up a thread on the client that does
That way receiving can be done in parallel with the client sending data
Or you could use 2 threads on the server side. One for receiving the data, posting data to be sent back to another thread doing the sending (you'll have to build up an internal queue in this case between the threads).
据我记得
IOUtils.copy()
不会刷新并且不会关闭流。看来你也没有调用“flush”或“close”。尝试一下。我相信这是你的问题。As far as I remember
IOUtils.copy()
does not flush and does not close the stream. It seems that you do not call neither flush nor close too. Try it. I believe that this is your problem.