[英]Java socket blocking
我正在尝试使用多个客户端连接创建服务器。 客户端首先发送用户输入的命令。然后服务器读取所有参数并将其作为对象发送给服务器。
但我的问题是,在一个命令之后,我的程序陷入僵局。 我做了一个解决方法,所以我的客户端发送命令,然后在服务器之后 - 说你可以发送查询 - 对象。 我怎样才能避免这种解决方法?
这是我的服务器。
try {
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
objectOut = new ObjectOutputStream(clientSocket.getOutputStream());
objectIn = new ObjectInputStream(clientSocket.getInputStream());
// communicate with client
if ("Hello Server".equals(in.readLine())) {
out.println("Connection with Server established");
}
else {
out.println("You picked the wrong house, fool! (wrong greeting)");
}
String inputLine;
while ((inputLine = in.readLine()) != null) {
if ("exit".equals(inputLine)) {
break;
}
else if ("ls".equals(inputLine)) {
execute_ls();
}
else if ("data".equals(inputLine)) {
out.println("o");
var query = (Query) objectIn.readObject();
exceute_data(query);
}
}
in.close();
out.close();
clientSocket.close();
} catch (Exception e) {
Logger.err(e.toString());
}
这是我在客户端的功能。
public CompletableFuture<Data> queryData(param) {
Data data_from_server;
CompletableFuture<Data> data_series = new CompletableFuture<>();
try {
outputData.println("data");
inputData.readLine();
objectOutputData.writeObject(param);
data_from_server = (Data) objectInputData.readObject();
data_series.complete(data_from_server);
if (data_from_server.getErrorMessage() != null) {
throw new Exception(data_from_server.getErrorMessage());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return data_series;
}
在此先感谢各位!
您认为BufferedReader
“缓冲”代表什么?
作为一项规则,您不能围绕同一个“源”输入流或读取器对象创建多个包装器,并期望一切正常工作 - 过滤器流(那些不是源的流,但您环绕另一个流;BufferedReader 是这种事情的一个例子,就像 InputStreamReader)被允许从底层输入源读取比提供任何请求数据所严格要求的更多; 某些过滤器流,例如 BufferedReader,实际上是明确指定的(例如,这是 BR 所做的唯一事情,因此得名)。
解决方案是永远不要有混合流。 要“取消混合”此流,请定义一个协议。 例如:
首先,客户端发送 1 个字节,表示它即将发送的命令的长度。 然后,它发送那么多字节(注意: BYTES ,而不是字符,你不应该在这里创建任何类型的 Reader 对象),然后你使用 US_ASCII 编码将其转换为一个字符串,然后对于每个命令你跳转到一个单独的代码片段。 例如,'exit' 命令不需要发送更多数据,但 'data' 命令将发送一个大端 32 位值,其中包含以下数据的大小。 然后使用 java 的内置序列化机制(即 ObjectInputStream)读取和解释该数据。
等等。
这导致了更多的认识:Java 内置的序列化机制几乎完全不适合这项工作; 这是一个你无法描述的协议(除了:“获取这个类文件,找到一个 JVM,确保类文件在它的类路径上,创建一个 ObjectInputStream,并在它上面调用 readObject”),这是非常低效的,充斥着如果您只坚持使用 java(在面对序列化对象时更改代码非常棘手),并且如果您向链中添加任何不是用 java 编写的工具,则无法阅读。 我建议你用别的东西。
一些替代方案:
https://yourserver.com/api/listAll
,在标头中使用某种身份验证令牌和/或会话令牌,如果在命令调用之间有要记住的状态数据。 然后在网络上搜索如何在 Java 中创建 REST API,您会发现大量选项,例如 JAX-RS 实现,如Jersey或Spark 。InputStream
,仔细阅读您需要的内容,并在几乎所有内容前加上“大小”以了解要读取的内容,而不会意外读取很多。 这相当复杂,这就是为什么我建议您不要采用此计划,而是选择上述其他 3 个选项之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.