簡體   English   中英

服務器客戶端通信在Outputstreams失敗

[英]Server Client communication fails at Outputstreams

我的程序基本上是:

  1. 客戶端向服務器發送一個字符串,

  2. 服務器基於此字符串創建一個ArrayList,

  3. ArrayList發送回客戶端。

這里失敗的是:

客戶端發送字符串后,服務器將接收它,並且不執行其他任何操作。 在這段時間內,客戶端繼續工作並獲得一個NullPointer。

客戶端:

    public static ArrayList<String> sendStringToServer(String report) {

    Socket socket;

    ArrayList<String> fieldsList = new ArrayList<String>();

    try {

        socket = new Socket("localhost", 2345);

        OutputStream os = socket.getOutputStream();
        PrintStream ps = new PrintStream(os, true);

        ps.println(report);
        ps.flush();

        //Here the debugger should stop and wait for server to create a List

        //at this point there is no answer, code breaks
        ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());

        Object object = objectInput.readObject();
        fieldsList = (ArrayList<String>) object;

        socket.close();

        return fieldsList;

    } catch (IOException e1) {

        e1.printStackTrace();
    } catch (Exception e) {

        e.printStackTrace();
    }
    return null;
}

}

服務器端:

public class Server {

private ServerSocket serverSocket;
private Socket clientSocket;
private String telegram;
private StringBuilder telegramSB;

public static void main(String[] args) throws IOException, JRException {

    new Server();
}
public Server() {

    try {
        serverSocket = new ServerSocket(2345);

        while (true) {

            clientSocket = serverSocket.accept();
            InputStream is = clientSocket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            try {

                //debugger goes to here and then stops
                telegram = br.readLine();

                int counter = 0;

                boolean startSeq = false;

                for (char ch : telegram.toCharArray()) {

                    if (counter == 0 && ch == '/') {

                        startSeq = true;
                    }

                    if (startSeq == true) {

                        telegramSB = new StringBuilder();
                        telegramSB.append(ch);
                    }

                    if (ch == '\n') {

                        if (telegram.length() < 255) {

                            sendListWithFields();

                        } else {

                            new Launcher(telegram).run();
                        }
                    }
                    counter++;
                }
            } catch (JRException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            }
        }
    } catch (IOException e) {

        System.out.println(e);
    }
}

我的猜測是BufferedReader正在等待填充其緩沖區,而您沒有發送足夠的數據來執行該操作並返回,因此它等待更多的數據通過,這是永遠不會做的(因為您的客戶端停止寫入並開始執行讀)。 您可以通過將更多的數據轉儲到客戶端上的OutputStream並將其刷新來臨時測試該理論。

如果是上述情況,則您可能不想使用BufferedReader,但是這里還有其他問題,這也意味着您可能無論如何都要避免使用PrintStream和BufferedReader進行通信和序列化。 例如,兩個不同的機器和JVM上的默認字符編碼可能不同。 當您創建PrintStream和InputStreamReader時,您未指定字符編碼,因此它們最終可能會不匹配,並且您寫的字符串(包括換行符)最終可能會被另一端完全不同地理解,這也可能是阻止它的原因(客戶端以一種方式對換行符進行編碼,但是服務器期望以完全不同的方式對其進行編碼),盡管我認為這種可能性較小。

如果你沒有使用PrintStream的話,我會建議,而不是使用DataOutputStream / DataInputStream類:

//Client
BufferedOutputStream bufout = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dout = new DataOutputStream(bufout);
dout.writeUTF(report);
dout.flush();

//Server
BufferedInputStream bufin = new BufferedInputStream(socket.getInputStream());
DataInputStream din = new DataInputStream(bufin);
String report = din.readUTF();

您仍然可以從BufferedIn / OutputStreams獲得緩沖,因此它將很有效,但是DataIn / OutputStreams將為您管理可變長度對象的終止-它們將發送一個長度作為字符串的前綴,以告知另一端確切要讀取多少字節,因此您不需要使用特殊字符來終止所編寫的字符串,這也意味着String的內容無關緊要。 在上面的示例中,即使字符串中包含換行符也可以正常工作,服務器仍會讀取直到第一個換行符,直到發送字符串的末尾為止,這將使它們在下一次發送時不同步/沿該流接收。

使用write / readUTF還會指定一種編碼(UTF-8),因此也不會出現不匹配的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM