我试过这个,但是在某个地方,我无法从服务器读取响应。 (响应采用XML格式)。
我已经读过,通过套接字写入需要缓冲,因为字符串断裂。不知怎的,当我使用jaxb unmarshaller并且它报告了一个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();
答案 0 :(得分:0)
您通过套接字发送XML,但服务器端没有回答。为了100%确定会发生什么,我们需要服务器代码和服务器错误消息。到目前为止,我看到了两件事,你可以做到:
在编写和刷新XML时,您可以调用socket.shutdownOutput()
。这会向服务器发送一个EOF,表明没有其他内容可供阅读。最新的服务器应该知道,它必须处理XML并产生结果。
您通过char
的流发送byte
字符串。希望服务器以与客户端发送它相同的方式理解它。由于希望在编程中没有多大帮助,你应该像这样包装输出流:Writer writer = new OutputStreamWriter(socket.shutdownOutput(), "UTF-8");
并执行write和flush与writer。请注意,您需要在服务器端对输入流执行相同操作(使用“UTF-8”包装为Reader)
答案 1 :(得分:0)
请将您的问题减少到显示错误的正在运行的代码。发布一些甚至不编译的代码,并不能真正帮助您理解您遇到的问题。即使在将此代码插入方法并导入java.io内容之后,仍有4个(!)未声明的变量:hd, rq, out and rd
。
为了解决您的问题并回答您的问题:
您不需要使用缓冲编写器,只需要确保编写要写入的所有内容(然后刷新或关闭流)。当客户端(接收者)在尝试解释数据之前,只要字节可用就必须从该流中读取。
如果你想实现不同的协议,你当然必须读/写,直到某个标记或任何表示你的传输完成。但是对于这个问题,我假设您只想传输一组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。这样做的通用方法可能是这样的:
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;
}
请记住,此方法既不会关闭流,也不会处理异常。