[英]Server Client communication fails at Outputstreams
我的程序基本上是:
客戶端向服務器發送一個字符串,
服務器基於此字符串創建一個ArrayList,
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.