我正在制作一个客户端-服务器 Java Swing 应用程序,我需要通过 ObjectOutputStream 发送请求。我从 LoginFrame 发出一个请求来检查登录名/密码是否正确,服务器接收数据,对其进行操作并成功发回应答。但是当我尝试再次调用服务器时,它只是没有收到它,服务器停止监听。
服务器:
public void runServer() throws IOException, ClassNotFoundException {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server started and listening " + port);
Model.getCountriesAndCities();
System.out.println(Model.getCountries()[0]);
System.out.println(Model.getCountriesMap());
for (int i = 0; i < 50; i++) {
Socket clientSocket = serverSocket.accept();
System.out.println("serversocket accepted");
System.out.println("before oos");
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
System.out.println("before ois");
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("server is listening");
Map<String, Object> methodData = (Map<String, Object>) ois.readObject();
System.out.println("Server: data received");
String methodName = (String) methodData.get("method");
Object arguments = methodData.get("arguments");
Object result = invokeMethod(methodName, arguments);
oos.writeObject(result);
System.out.println("Server: data sent");
oos.flush();
}
}
客户端方法:
public static int checkUser(String login, String password, Client client) {
String query = "SELECT EXISTS(SELECT * FROM users WHERE login = '" + login + "' and password = '" + password + "') as isExist";
String methodName = "CRUDUtils.checkUser";
try {
Map<String, Object> methodData = new HashMap<>();
methodData.put("method", methodName);
methodData.put("arguments", query);
client1.oos.writeObject(methodData);
System.out.println("Client: query sent");
client1.oos.flush();
int check = (Integer) client1.ois.readObject();
System.out.println("chekUser: answer received");
return check;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static String[] getCountries(Client client) {
String query = " ";
String methodName = "Model.getCountries";
ObjectOutputStream oos;
ObjectInputStream ois;
try {
Map<String, Object> methodData = new HashMap<>();
methodData.put("method", methodName);
methodData.put("arguments", query);
client1.oos.writeObject(methodData);
System.out.println("Client: query sent");
client1.oos.flush();
System.out.println("before ois");
String[] check = (String[]) client1.ois.readObject();
System.out.println("getCountries: answer received");
return check;
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
我还有客户端类来启动套接字和摆动框架:
public static void main(String[] args) {
Client klientura = new Client();
try {
klientura.socket = new Socket("localhost", 4444);
klientura.oos = new ObjectOutputStream(klientura.socket.getOutputStream());
klientura.ois = new ObjectInputStream(klientura.socket.getInputStream());
System.out.println("client connected");
Control.client1 = klientura;
LoginFrame loginFrame = new LoginFrame(klientura);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
我尝试替换ObjectOutput和InputOutput,但没有成功。 我尝试在发送数据后刷新每个 oos,但没有成功。 我尝试在使用后关闭所有 oos 和 ois,但没有成功。 我尝试了一切,这就是为什么现在这段代码一团糟。
方法 checkUser 工作得很好,但是当运行 getCountries 时,客户端进程只是在线停止
String[] check = (String[]) client1.ois.readObject();
客户端控制台中的最后一条消息是“before ois”,这意味着client1.oos.writeObject(methodData)
已完成,但服务器没有响应。
服务器控制台中的最后一条消息是“服务器:数据已发送”,这意味着服务器已将数据发送到 checkUser 方法并停止侦听。
根据文档,accept() 侦听与此套接字建立的连接并接受它。该方法会阻塞,直到建立连接为止。
您当前的实现看起来像是为每个请求重复使用相同的连接。因此,您的服务器在accept() 方法处阻塞。要解决此问题,您可以为每个对服务器的请求创建一个新的套接字实例(连接),或者重构您的服务器实现,以便不会阻止侦听新连接。