[英]Reading XML from Socket streams
我有一個套接字連接,我希望通過該套接字發送XML消息,使用DOM類( DocumentBuilder
等 )來構造和解析XML文檔,並且我找不到解決在等待消息時關閉連接的好方法。
消息可能以任何順序到達(即,我不知道哪一端將發送下一條消息),並且我想避免使用任何基於sleep()
解決方案來進行阻止-我想學習如何做得更好。 我嘗試了以下設置的多種變體:
class XML {
static Message readMessage(InputStream s) {
// try/catch and setup of builder omitted for brevity
Document doc = builder.parse(s);
// Traverse the doc tree to built the Message, then return
}
static void writeMessage(Message m, OutputStream s) {
// Build a Document from the provided message
Transformer transformer = tf.newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult(output));
output.write('\n');
}
}
class Connection {
Socket s;
Thread reader;
Connection(Socket s) {
this.s = s;
reader = new Thread(new Runnable() {
void run() {
while (true) {
Message m = XML.readMessage(s.getInputStream());
// Handle the message here, e.g. by dispatching UI events
}
}
});
reader.start();
}
void sendMessage(Message msg) {
XML.writeMessage(msg, s.getOutputStream());
}
void close() {
if (reader.isAlive()) {
reader.interrupt();
}
if (!socket.isClosed()) {
socket.close();
}
}
}
我可以通過簡單地在各個端分別使用Socket
實例化一個Connection
來使服務器和客戶端相互連接,然后開始等待消息。 發送和接收消息也可以正常工作。
但是,我想不出一種干凈地關閉連接的方法。 我不斷遇到各種異常。 確切的消息取決於上面框架中的實現細節,但是據我所知,它們都是在套接字關閉后讀取線程嘗試讀取消息,或者在讀取線程仍在讀取時套接字關閉時出現的。 我總是使用上面的close()
方法關閉連接。
由於我只是將流傳遞給DOM庫,因此我無法精確控制其讀取方式。
如何正確終止連接,而不會在讀取器線程中引起異常?
即使我對這種解決方案的丑陋程度有所畏懼,我還是設法產生了一些切實可行的方法。 這就是我所做的(並且由於它有效,因此我將其發布為答案):
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader breader = new BufferedReader(reader);
String xml = breader.readLine();
InputStream newstream = new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8")));
Document doc = builder.parse(newstream);
也就是說,我不得不實例化四個額外的對象,最后得到一個與我最初使用的對象類型完全相同的對象,只是為了使解析器意識到它具有整個文檔。
如果有更好的方法,我將很樂意接受並支持所有描述此問題的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.