我已经创建了一个多线程服务器,它连接到MySQL数据库并接受来自客户端的请求。服务器应始终从客户端命令进行侦听,但这不会发生。它只接受一个命令将它发送到数据库并得到我需要的任何东西,然后就完成了。它不再接受任何命令。 我为您提供了客户端和服务器。
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.ConnectException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class Airlines {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket connection = null;
int port = 1234;
try{
serverSocket = new ServerSocket(port);
while ((connection = serverSocket.accept())!=null){
System.out.println("Client connected!");
Thread client = new Thread (new AirlinesThread(connection));
client.start();
}
}catch (IOException e){
System.out.println("Binding unsuccesful...");
}
}
}
class AirlinesThread implements Runnable{
Socket connection = null;
public AirlinesThread (Socket connection){
this.connection = connection;
}
private static Connection connect(String url, String user, String password){
Connection result = null;
try{
result = DriverManager.getConnection(url, user, password);
System.out.println("Database connection successful!");
}
catch(SQLException e){
System.out.println("Could not connect to the database!");
}
return result;
}
String url = "jdbc:mysql://localhost:3306/Airlines";
String user = "root";
String pass = "123456";
Connection link = AirlinesThread.connect(url, user, pass);
Statement stmt = null;
ResultSet resultSet = null;
public void run() {
PrintWriter socketOut = null;
DataInputStream socketIn = null;
try{
socketOut = new PrintWriter(this.connection.getOutputStream(),true);
socketIn = new DataInputStream(this.connection.getInputStream());
int command;
boolean exists = false;
socketOut.flush();
loop:do{
socketOut.flush();
command = socketIn.readInt();
switch (command){
case 1:
try{
stmt = link.createStatement();
resultSet = stmt.executeQuery("select Flight.id, Flight.Date, Flight.Time, Flight.Total_Flight_Time, Airports.Departure, Airports.Arrivals FROM Flight, Airports WHERE Flight.id = Airports.Flight");
socketOut.flush();
socketOut.println("FlightID\tDate\t\tTime\t\tTotal Time\tDeparture\tArrivals");
while (resultSet.next()) {
socketOut.println(resultSet.getString("Flight.id")+"\t\t"+resultSet.getDate("Flight.Date")+"\t"+resultSet.getString("Flight.Time")+"\t"+resultSet.getString("Flight.Total_Flight_Time")+"\t\t"+resultSet.getString("Airports.Departure")+"\t"+resultSet.getString("Airports.Arrivals"));
}
}
catch(SQLException e){
System.out.println("Something went wrong at 1");
}
break;
case 2:
try{
stmt = link.createStatement();
resultSet = stmt.executeQuery("select Flight.id, Flight.Date, Flight.Time, Pilots.First_Name, Pilots.Last_Name from Flight RIGHT JOIN Pilots ON Flight.id = Pilots.FlightID;");
socketOut.flush();
socketOut.println("FlightID\tDate\t\tTime\t\tFirst Name\tLast Name");
exists = resultSet.next();
if(exists == false){
socketOut.flush();
socketOut.println("Wrong request!");
System.out.println("Wrong query at 2");
}
while (resultSet.next()) {
socketOut.flush();
socketOut.println(resultSet.getString("Flight.id")+"\t\t"+resultSet.getDate("Flight.Date")+"\t"+resultSet.getString("Flight.Time")+"\t"+resultSet.getString("Pilots.First_Name")+"\t\t"+resultSet.getString("Pilots.Last_Name"));
}
}
catch(SQLException e){
System.out.println("Something went wrong at 2");
}
break;
case 3:
try{
stmt = link.createStatement();
resultSet = stmt.executeQuery("select Food.Breakfast, Airplanes.Plane_Model FROM Food, Airplanes Where Food.FlightID=Airplanes.Plane_Model;");
exists = resultSet.next();
if(exists == false){
socketOut.flush();
socketOut.println("Wrong request!");
System.out.println("Wrong query at 3");
}
while (resultSet.next()) {
socketOut.flush();
socketOut.println(resultSet.getString("Food.Breakfast")+"\t\t"+resultSet.getString("Airplanes.Plane_Model"));
}
}
catch(SQLException e){
System.out.println("Something went wrong at 3");
}
break;
case 0 :
socketOut.flush();
socketOut.println("Exitting...");
break loop;
default:
System.out.println("Unknown command!");
socketOut.println("Unknown command!");
break;
}
}while(command!=0);
System.out.println("Closing connection to the client!");
}catch (IOException e){
e.printStackTrace();
}finally{
try{
if (socketIn!=null) socketIn.close();
if (socketOut!=null) socketOut.close();
if (connection!=null) connection.close();
System.out.println("Connection to server closed!");
}
catch(IOException e){
System.err.println("Could not close connection!");
}
}
try{
if(stmt != null) stmt.close();
if(resultSet != null) resultSet.close();
if(link != null) link.close();
System.out.println("Database connection closed successfully!");
}catch(SQLException ex){
System.out.println("Could not close connection to the database!");
}
}
}

客户:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.Socket;
import java.util.Scanner;
public class AirlinesClient {
public static void main(String[] args) {
Socket connection = null;
Scanner socketIn = null;
DataOutputStream socketOut = null;
int port = 1234;
String host = "localhost";
Scanner keyIn = new Scanner(System.in);
try{
try{
connection = new Socket(host,port);
socketIn = new Scanner(new BufferedReader(new InputStreamReader(connection.getInputStream())));
socketOut = new DataOutputStream(connection.getOutputStream());
}catch(ConnectException e){
System.out.println("Could not connect to the host!");
return;
}
System.out.println("Successfully connected to the server!");
System.out.println("Select from the options below:\n1: Check schedules\n2: Check pilots shifts\n3: Check corresponding airplanes and food offered\n4: Possible pilot shift changes");
loop:do{
int command;
socketOut.flush();
command = keyIn.nextInt();
socketOut.flush();
socketOut.writeInt(command);
while (socketIn.hasNext()){
System.out.println(socketIn.nextLine());
}
}while(keyIn.nextInt()!=0);
System.out.println("Closing connection to server!");
}catch(IOException e){
e.printStackTrace();
} finally{
try{
if(socketIn!=null) socketIn.close();
if(socketOut!=null) socketOut.close();
if(connection!=null) connection.close();
}
catch(IOException e){
System.err.println("Socket could not be closed!");
}
}
}
}

答案 0 :(得分:0)
问题是您在客户端使用Scanner
。执行挂起socketIn.hasNext()
,因为
public boolean hasNext()
如果此扫描器的输入中有另一个标记,则返回true。在等待输入扫描时,此方法可能会阻塞。扫描仪不会超过任何输入。
代码将在新输入或基础流关闭的情况下继续(我们不希望这样)。你必须有一种方法来知道传输结束而不关闭流。看下面非常简单的一个。
在服务器中的每个try-catch block
结束时
socketOut.println("$$$");
在客户端中将socketIn
声明为BufferedReader
并将其实例化为
socketIn = new BufferedReader(new InputStreamReader(connection.getInputStream()));
在客户端也将loop
循环更改为
int command = keyIn.nextInt();
do {
socketOut.flush();
socketOut.writeInt(command);
String line;
while (!(line = socketIn.readLine()).equals("$$$"))
System.out.println(line);
} while ((command = keyIn.nextInt()) != 0);
这也将修复您对keyIn.nextInt()
的双重检查。在你的代码中,你每个循环调用它两次(除了第一次迭代)。