gpt4 book ai didi

java - 服务器客户端通信在输出流处失败

转载 作者:太空宇宙 更新时间:2023-11-04 13:39:10 24 4
gpt4 key购买 nike

我的程序基本上是:

  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 将为您管理可变长度对象的终止 - 它们将发送一个字符串前缀的长度,以告诉另一端到底要读取多少字节,因此您不需要使用特殊字符来终止您编写的字符串,这也意味着您的字符串内容是什么并不重要。在上面的示例中,即使如果您的字符串中包含换行符,服务器也会读取直到第一个换行符,而不是您发送的字符串末尾,这将使它们在沿着该流的下一个发送/接收时不同步。

使用 write/readUTF 还指定编码 (UTF-8),因此也不存在不匹配。

关于java - 服务器客户端通信在输出流处失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31384336/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com