繁体   English   中英

通过 java Sockets 发送 xml 字符串的最佳方式是什么?

[英]what is the best way to send xml string over java Sockets?

我试过这个,但是在某个地方我无法读取服务器的响应。 (响应采用 XML 格式)。

我已经读过由于字符串断裂,通过套接字写入需要缓冲。 不知何故,当我使用 jaxb 解组器并报告 SAX EOF 异常时,我发现这是真的,这意味着读取的 xml 不完整。

请问如何正确缓冲写入和缓冲读取?

StringBuilder sb = new StringBuilder();
sb.append("<estel>");
sb.append("<header><requesttype>").append(hd.getRequestType()).append("</requesttype></header>");
sb.append("<request>");
sb.append("<agentcode>").append(rq.getAgentCode()).append("</agentcode>");
sb.append("<pin>").append(rq.getPin()).append("</pin>");
sb.append("<destination>").append(rq.getDestination()).append("</destination>");
sb.append("<agenttransid>").append(rq.getAgentTransId()).append("</agenttransid>");
sb.append("<vendorcode>").append(rq.getVendorCode()).append("</vendorcode>");
sb.append("<amount>").append(rq.getAmount()).append("</amount>");
    sb.append("<productcode>").append(rq.getProductCode()).append("</productcode>");
    sb.append("<comments>").append(rq.getComments()).append("</comments>");
    sb.append("<clienttype>").append(rq.getClientType()).append("</clienttype>");
sb.append("</request></estel>");


    Socket socket = new Socket("41.206.23.21",7101);
    OutputStream os = socket.getOutputStream();
    InputStream in = socket.getInputStream();

    OutputStream buf = new BufferedOutputStream(os);    
    out = new OutputStreamWriter(buf);

    System.out.printf("\nxml is %s",sb.toString());   
   System.out.print("\n--------writing--to--socket-----");
    out.write(sb.toString());
    out.flush();

    //read response
    InputStream bui = new BufferedInputStream(in);
  rd = new InputStreamReader(bui);
   System.out.print("\nxml response"+rd.toString());

   in.close();
   out.close();
   socket.close();

您通过套接字发送 XML,但服务器端没有应答。 为了 100% 确定会发生什么,我们需要服务器代码和服务器错误消息。 到目前为止,我看到两件事,你可以做:

  1. 在编写和刷新 XML 时,您可以调用socket.shutdownOutput() 这会向服务器发送一个 EOF,表明没有更多内容可读取。 比服务器应该知道的最新,它必须在 XML 上工作并产生结果。

  2. 您通过byte的 Stream 发送一个char字符串。 希望服务器以与客户端发送它相同的方式理解这一点。 由于希望对编程没有真正的帮助,您应该像这样包装输出流: Writer writer = new OutputStreamWriter(socket.shutdownOutput(), "UTF-8"); 并与作家一起写作和冲洗。 请注意,您需要在服务器端对输入流执行相同操作(使用“UTF-8”包装为 Reader)

请将您的问题简化为显示错误的运行代码。 发布一些甚至无法编译的代码,并不能真正帮助您理解您遇到的问题。 即使在将此代码安装到方法中并导入 java.io 内容之后,仍有 4 个(!)未声明的变量: hd, rq, out and rd

为了帮助您解决问题并回答您的问题:

  1. 您不需要使用缓冲写入器,您只需要确保写入您想要写入的所有内容(然后刷新或关闭流)。 只要字节可用,客户端(接收者)当然必须在尝试解释数据之前从该流中读取。

  2. 如果你想实现一个不同的协议,你当然必须读/写直到某个标记或任何表明你的传输完成的东西。 但是,对于这个问题,我假设您只想传输一组 XML 数据。

对于写作,您可以使用简单的OutputStream一次性写入 String 。 像这样的代码可以完成这项工作:

StringBuilder sb = new StringBuilder();
//...
Socket socket = new Socket("41.206.23.21", 7101);
OutputStream os = socket.getOutputStream();
os.write(sb.toString().getBytes());
os.flush();

阅读后,您还可以使用简单的InputStream 为确保获得所有内容,您通常应该读取数据并将其全部写入一个中间字节数组,然后您可以将其转换回您的字符串。 这样做的通用方法可能是这样的:

  String read(InputStream in) throws IOException {
    byte[] buffer = new byte[8192];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int got;
    while ((got = in.read(buffer)) > -1) {
      out.write(buffer, 0, got);
    }
    byte[] data = out.toByteArray();
    String result = new String(data);
    return result;
  }

请记住,此方法既不关闭流,也不处理异常。

暂无
暂无

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

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