它让我疯狂地试图解决这个问题。
我正在编写一个java服务器来处理android应用程序。它们传递文本字符串和xml。
目前简单的套接字通信看起来很好,但是当我尝试使用变压器而不是简单的println时,它会崩溃。
服务器代码如下
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class javamultithreadedserver implements Runnable {
Socket csocket;
static int listenport = 6021;
public static final String endOfCom = "endofcom";
String connectionname;
public javamultithreadedserver(Socket csocket, String connectionname) {
this.csocket = csocket;
this.connectionname = connectionname;
}
public static void main(String[] args) throws Exception {
int listentoport = 0;
//System.out.println(args.length);
if (args.length == 1){
listentoport = Integer.parseInt(args[0]);
} else{
listentoport = listenport;
}
ServerSocket ssock = new ServerSocket(listentoport);
System.out.println("Listening at port " + listentoport);
while (true) {
Socket sock = ssock.accept();
System.out.println("Connected. from: " + sock.getInetAddress().getHostAddress() + " " + sock.getInetAddress().getHostName() + " port: " + sock.getPort() + " " + sock.getInetAddress().getCanonicalHostName());
new Thread(new javamultithreadedserver(sock, sock.getInetAddress().getHostAddress() + " " + sock.getInetAddress().getHostName() + " " + sock.getInetAddress().getCanonicalHostName())).start();
}
}
@Override
public void run() {
try {
PrintWriter out = new PrintWriter(csocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(csocket.getInputStream()));
PrintStream pstream = new PrintStream (csocket.getOutputStream(), true);
String inputLine, outputLine;
System.out.println(connectionname + ": listening for query information.");
while ((inputLine = in.readLine()) != null) {
System.out.println(connectionname + ": " + inputLine);
//out.write("received something");
DBQuery q = new DBQuery(inputLine + DBQuery.regexsplit + "connectionname" + DBQuery.regexsplit + connectionname);
DOMSource dmsource = q.returns();
***//StreamResult consoleResult = new StreamResult(System.out); //debug***
StreamResult consoleResult = new StreamResult(pstream);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Thread.sleep(100);
***transformer.transform(dmsource, consoleResult);***
//out.println("println this is a testprogram"); // client receive ok
pstream.flush();
System.out.println(connectionname + ": reply sent.");
if (inputLine == endOfCom){
System.out.println(connectionname + ": is satisfied and terminated communication.");
break;
}
}
pstream.close();
csocket.close();
}catch (IOException e) {
System.out.println(e);
}catch (Exception e) {
System.out.println(e);
}
}
}
Android客户端代码如下:
public void run() {
if (barcode.length() > 0) {
Socket socket = null;
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
socket.setSoTimeout(10000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write(barcode + ENDL);
if(out.checkError()){
showToUI("PrintWriter had error");
} else {
showToUI("Query sent");
}
int i = 0;
while (true) {
try{
if (**(serverResponse = in.readLine()) != null**) {
if(serverResponse == endOfCom){
Log.i("communicated all data", "bye");
out.write(endOfCom + ENDL);
break;
} else{
}
Log.i("server says", serverResponse);
}
//Log.i("server says", (serverResponse == null? "null" :serverResponse ));
}catch(SocketTimeoutException e){
showToUI(barcode + ": Server did not respond in time");
if (i++ > 2) {
break;
}
}
}
} catch (final UnknownHostException e1) {
showToUI(e1.toString());
} catch (final IOException e1) {
showToUI(e1.toString());
} finally{
try {
socket.close();
} catch (IOException e) {
showToUI(e.toString());
}
}
}else{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Please enter something in barcode", Toast.LENGTH_SHORT).show();
}
});
}
}
我测试过返回的xml结果没问题,如果Stream Result设置为System.out
而不是PrintStream pstream
,那么一切都完美地打印到控制台。
无论是否有pstream.flush()
,客户都未在(serverResponse = in.readLine()) != null
收到回复。
同样,基于out
socket
的{{1}}套件的PrintWriter pstream
成功地向客户提供了反馈。调用out.println("println this is a testprogram");
后,客户端会在Log.i("server says", serverResponse);
行接收日志确定。
有一点需要注意的是,回复通常很长,最多可达65536个字符甚至更多,我不知道是否有任何含义,我试图在android app上创建一个Buffered reader大于回复xml,它仍然无法正常工作。机器在本地网络上进行通信,java服务器程序在与Android模拟器不同的机器上运行。
感谢任何帮助,这已经持续了好几天。
答案 0 :(得分:0)
readLine()
不会返回null。当它确实返回null时,你需要突破循环。并且不要将字符串s与==。