解组Socket的InputStream会关闭Socket吗?

9
我可以为您进行翻译。以下是您需要翻译的内容:

我有一个服务器-客户端架构,在这个架构中,客户端向服务器发送一个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,这破坏了我的计划......有什么解决方法吗?
2个回答

10

XMLEntityManager类调用InputStream的close方法。

您可以使用FilterInputStream来避免对基础流进行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()));

因此,JAXB框架仍会调用流的close()方法,但现在它已被你自己的流实例过滤掉,socket流保持打开状态。


7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接