трансформатор в розетку не работает

Это сводит меня с ума, когда я целыми днями пытаюсь решить эту проблему.

Я пишу 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.

Также PrintWriter out, основанный на том же Socket socket из pstream, успешно дал обратную связь клиенту. При вызове out.println("println this is a testprogram"); клиент получил лог в строке Log.i("server says", serverResponse); OK.

Следует отметить, что ответ обычно довольно длинный, может быть до 65536 символов или даже больше, я не знаю, имеет ли это какое-либо значение, я пытался создать буферизованный ридер в приложении для Android больше, чем ответный xml , все равно не получилось. Машины общаются по локальной сети, программа Java-сервера работает на другой машине, отличной от эмулятора Android.

Любая помощь приветствуется, это продолжалось несколько дней и нигде.


person Jimmy Chi Kin Chau    schedule 07.10.2015    source источник


Ответы (1)


readLine() не вернет null, пока одноранговый узел не закроет соединение. И когда он возвращает null, вам нужно выйти из цикла. И не сравнивайте строку s с ==.

person user207421    schedule 07.10.2015
comment
Благодаря EJP, закрытие действительно вернулось. Однако в справочнике для разработчиков Android указано, что public String readLine() возвращает следующую строку текста, доступную из этого средства чтения. Я думаю, что основная проблема в том, что в настоящее время он ничего не возвращает, пока одноранговый узел не закроется, что не было указано в ссылке. Я вырвусь из цикла, текущая версия пересматривалась так много раз, что я сосредоточен на получении отдачи, а не на потоке программы. Также я не уверен, буду ли я использовать == или .equals(), .equals() выдает ошибку, когда возвращает null, может быть, .equals(String(null)). - person Jimmy Chi Kin Chau; 08.10.2015
comment
Проблема теперь устранена путем вызова pstream.println() после convert.transform(dmsource, consoleResult), теперь клиент получает ответ от сервера в readline(), хотя я понятия не имею, что это должно быть, возможно transform.transform() не создает конечный символ новой строки. Спасибо EJP за первоначальную подсказку. - person Jimmy Chi Kin Chau; 08.10.2015