[英]Java server would accept only one entry from my client
I've made a multithreaded server that connects to a MySQL database and accepts requests from a client. 我已经制作了一个多线程服务器,该服务器连接到MySQL数据库并接受来自客户端的请求。 The server should always be listening from client commands but this doesn't happen.
服务器应该始终在侦听客户端命令,但这不会发生。 It just accepts one command sends it to the database and gets whatever I need, then it's done.
它只接受一个命令将其发送到数据库并获取我需要的任何内容,然后就完成了。 It doesn't accept any more commands.
它不再接受任何命令。 I provide you with the client and the server.
我为您提供客户端和服务器。
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!"); } } }
The client: 客户端:
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!"); } } } }
The problem is that you're using Scanner
in your client. 问题是您在客户端中使用
Scanner
。 Execution hangs on socketIn.hasNext()
, because 执行挂在
socketIn.hasNext()
,因为
public boolean hasNext()
Returns true if this scanner has another token in its input.
如果此扫描程序的输入中包含另一个令牌,则返回true。 This method may block while waiting for input to scan.
等待输入扫描时,此方法可能会阻塞。 The scanner does not advance past any input.
扫描仪不会前进超过任何输入。
The code will proceed in case there's new input or underlying stream is closed (and we don't want that). 如果有新输入或底层流关闭(并且我们不希望这样做),则将继续执行代码。 You have to have a way of knowing end of transmission without closing the stream.
您必须有一种无需关闭流即可知道传输结束的方法。 Look below for very simple one.
在下面查找非常简单的一个。
At the end of every try-catch block
in your server put 在服务器中每个
try-catch block
的末尾放置
socketOut.println("$$$");
In client declare socketIn
as BufferedReader
and instantiate as 在客户端中,将
socketIn
声明为BufferedReader
并实例化为
socketIn = new BufferedReader(new InputStreamReader(connection.getInputStream()));
In client also change your loop
loop to 在客户端中也将您的
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);
This will also fix your double checking for keyIn.nextInt()
. 这也将修复您对
keyIn.nextInt()
双重检查。 In your code you're calling it twice per loop (apart from first iteration). 在您的代码中,每个循环调用两次(除了第一次迭代)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.