我正在开发一个Java客户端,它通过套接字连接到服务器并发送/接收XML消息。我知道消息的架构是什么。我目前正在使用它,但它感觉很乱,我还没有测试它,看它是如何处理从服务器一次发送的多个XML。
以下是代码:
private static BufferedReader socketIn;
private static PrintWriter socketOut;
private static final String SERVICES_FILE = "/etc/services";
public static void main(String[] args) {
int port = getServicePortByName("Service1", "tcp");
try {
logger.info("Creating socket port with ip: " + InetAddress.getLocalHost() + " and port: " + port);
Socket socket = new Socket(InetAddress.getLocalHost(), port);
socketOut = new PrintWriter(socket.getOutputStream(), true);
String message = createMessageXML("LOGIN");
socketOut.println(message);
socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder inputLine = new StringBuilder();
String tmp;
while (true) {
//loop to keep listening/parsing
while(socketIn.ready()) {
tmp = socketIn.readLine();
inputLine.append(tmp);
}
if(inputLine.length() > 0) {
parseReceivedMessage(inputLine.toString());
}
inputLine.replace(0, inputLine.length(), "");
}
} catch (UnknownHostException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
parseReceivedMessage方法只接受一个String并将其转换为Document对象。我的问题是,有没有更好或更清晰的方法来做这个而不是使用StringBuilder?我最初想将InputStream传递给DOM构建器解析方法。 我看到一些使用ByteArray流的例子,但我遇到了一些问题。如果有任何需要澄清,请告诉我。
答案 0 :(得分:1)
ready()
不是消息结束的有效测试。完全摆脱它和StringBuilder
和readLine()
调用,只需将输入流直接传递给DOM解析器。
答案 1 :(得分:1)
我强烈建议你围绕XML消息设计一个框架协议。使用长度值为每个XML消息添加前缀,该长度值指定要传输的字节数,然后发送XML本身(以字节为单位,而不是字符)。接收器然后可以读取长度,然后读取指定的字节数并将它们传递给XML解析器,然后读取下一个长度,依此类推。例如:
private static DataInputStream socketIn;
private static DataOutputStream socketOut;
private static final String SERVICES_FILE = "/etc/services";
public static void main(String[] args) {
int port = getServicePortByName("Service1", "tcp");
try {
logger.info("Creating socket port with ip: " + InetAddress.getLocalHost() + " and port: " + port);
Socket socket = new Socket(InetAddress.getLocalHost(), port);
socketIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
socketOut = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
byte[] message = createMessageXML("LOGIN");
socketOut.writeInt(message.length());
socketOut.write(message, 0, message.length());
int len = socketIn.readInt();
if (len > 0)
{
message = new byte[len];
socketIn.readFully(message);
parseReceivedMessage(message);
}
} catch (UnknownHostException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
}
}