繁体   English   中英

解组 Socket 的 InputStream 会关闭 Socket?

[英]Unmarshalling a Socket's InputStream closes the Socket?

我有一个服务器-客户端架构,其中客户端将 XML 发送到服务器,服务器读取它并从中生成 PDF 并将其发送回客户端。

在客户端:

JAXBElement<Xml> xml = ...
Socket sock = ...
Marshaller marshaller = ...
marshaller.marshal(xml, sock.getOutputStream());
sock.shutdownOuput();    

同时在服务器端:

ServerSocket server = ...
Socket client = server.accept();
Unmarshaller unmarshaller = ...
// client.isClosed() -> false
JAXBElement<Xml> xml =
  (JAXBElement<Xml>)) unmarshaller.unmarshall(client.getInputStream());
// client.isClosed() -> true
Pdf pdf = new Pdf(xml);
client.getOutputStream().write(pdf.toBytes());
// "socket is closed" IOException is thrown

如果我不解组客户端的InputStream (在服务器端)并且只是发回一个虚拟 PDF 那么一切都会顺利进行。 所以,我不得不假设Unmarshaller关闭了它给定的InputStream ,因此隐式关闭了客户端Socket毁了我的一天......

关于解决这个问题的任何想法?

class XMLEntityManager 在 InputStream 上调用 close。

您可以使用FilterInputStream来避免底层 stream 的 close() 调用。

子类 FilterInputStream 并用空主体覆盖 close() 方法:

public class MyInputStream extends FilterInputStream {
  public MyInputStream(InputStream in) {
    super(in);
  }

  @Override 
  public void close() {
    // do nothing
  }
}

然后将您的 unmarshall() 调用更改为

JAXBElement<Xml> xml =
    (JAXBElement<Xml>)) unmarshaller.unmarshall(new MyInputStream(client.getInputStream()));

So the JAXB framework still calls close() on the stream, but it's now filtered out by your own stream instance and the socket stream remains open.

如果您不想像 vanje 建议的那样在代码中显式覆盖 InputStream, Apache commons-io提供了一个实现这一点的实现:

看一眼:

CloseShieldInputStream

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM