2015-04-04 91 views
1

我製作了一個多線程服務器,它連接到MySQL數據庫並接受來自客戶端的請求。服務器應始終從客戶端命令進行偵聽,但這種情況不會發生。它只接受一個命令將其發送到數據庫並獲取我需要的任何內容,然後完成。它不接受任何更多的命令。 我爲您提供客戶端和服務器。Java服務器將只接受來自我的客戶端的一個條目

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 { 
 
\t public static void main(String[] args) { 
 
\t \t ServerSocket serverSocket = null; 
 
\t \t Socket connection = null; 
 
\t \t int port = 1234; 
 
\t \t try{ 
 
\t \t \t serverSocket = new ServerSocket(port); 
 
\t \t \t while ((connection = serverSocket.accept())!=null){ 
 
\t \t \t System.out.println("Client connected!"); 
 
\t \t \t Thread client = new Thread (new AirlinesThread(connection)); 
 
\t \t \t client.start(); 
 
\t \t \t } 
 
\t \t }catch (IOException e){ 
 
\t \t \t System.out.println("Binding unsuccesful..."); 
 
\t \t } 
 
\t } 
 

 
} 
 
class AirlinesThread implements Runnable{ 
 
Socket connection = null; 
 
public AirlinesThread (Socket connection){ 
 
\t 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; 
 
    } 
 
\t String url = "jdbc:mysql://localhost:3306/Airlines"; 
 
\t String user = "root"; 
 
\t String pass = "123456"; 
 
\t Connection link = AirlinesThread.connect(url, user, pass); 
 
\t Statement stmt = null; 
 
\t ResultSet resultSet = null; 
 
\t public void run() { 
 
\t \t PrintWriter socketOut = null; 
 
\t \t DataInputStream socketIn = null; 
 
\t \t try{ 
 
\t \t socketOut = new PrintWriter(this.connection.getOutputStream(),true); 
 
\t \t socketIn = new DataInputStream(this.connection.getInputStream()); 
 
\t \t int command; 
 
\t \t boolean exists = false; 
 
\t \t socketOut.flush(); 
 
\t \t loop:do{ 
 
\t \t \t socketOut.flush(); 
 
\t \t \t command = socketIn.readInt(); 
 
\t \t \t switch (command){ 
 
\t \t \t case 1: 
 
\t \t \t \t try{ 
 
\t \t \t \t  stmt = link.createStatement(); 
 
\t \t \t \t  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"); 
 
\t \t \t \t  socketOut.flush(); 
 
\t \t \t \t  socketOut.println("FlightID\tDate\t\tTime\t\tTotal Time\tDeparture\tArrivals"); 
 
\t \t \t \t  while (resultSet.next()) { 
 
\t \t \t \t  \t 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")); 
 
\t \t \t \t   
 
\t \t \t \t  } 
 
\t \t \t \t  } 
 
\t \t \t \t  catch(SQLException e){ 
 
\t \t \t \t  \t System.out.println("Something went wrong at 1"); 
 
\t \t \t \t  } 
 
\t \t \t \t break; 
 
\t \t \t case 2: 
 
\t \t \t \t try{ 
 
\t \t \t \t  stmt = link.createStatement(); 
 
\t \t \t \t  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;"); 
 
\t \t \t \t  socketOut.flush(); 
 
\t \t \t  \t socketOut.println("FlightID\tDate\t\tTime\t\tFirst Name\tLast Name"); 
 
\t \t \t  \t exists = resultSet.next(); 
 
\t \t \t \t  if(exists == false){ 
 
\t \t \t \t  \t socketOut.flush(); 
 
\t \t \t \t  \t socketOut.println("Wrong request!"); 
 
\t \t \t \t  \t System.out.println("Wrong query at 2"); 
 
\t \t \t \t  } 
 
\t \t \t \t  while (resultSet.next()) { 
 
\t \t \t \t  socketOut.flush(); 
 
\t \t \t \t  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")); 
 
\t \t \t \t  } 
 
\t \t \t \t  } 
 
\t \t \t \t  catch(SQLException e){ 
 
\t \t \t \t  \t System.out.println("Something went wrong at 2"); 
 
\t \t \t \t  } 
 
\t \t \t \t break; 
 
\t \t \t case 3: 
 
\t \t \t \t try{ 
 
\t \t \t \t  stmt = link.createStatement(); 
 
\t \t \t \t  resultSet = stmt.executeQuery("select Food.Breakfast, Airplanes.Plane_Model FROM Food, Airplanes Where Food.FlightID=Airplanes.Plane_Model;"); 
 
\t \t \t \t  exists = resultSet.next(); 
 
\t \t \t \t  if(exists == false){ 
 
\t \t \t \t  \t socketOut.flush(); 
 
\t \t \t \t  \t socketOut.println("Wrong request!"); 
 
\t \t \t \t  \t System.out.println("Wrong query at 3"); 
 
\t \t \t \t  } 
 
\t \t \t \t  while (resultSet.next()) { 
 
\t \t \t \t  socketOut.flush(); 
 
\t \t \t \t  socketOut.println(resultSet.getString("Food.Breakfast")+"\t\t"+resultSet.getString("Airplanes.Plane_Model")); 
 
\t \t \t \t   
 
\t \t \t \t  } 
 
\t \t \t \t  } 
 
\t \t \t \t  catch(SQLException e){ 
 
\t \t \t \t  \t System.out.println("Something went wrong at 3"); 
 
\t \t \t \t  } 
 
\t \t \t \t break; 
 
\t \t \t case 0 : 
 
\t \t \t \t socketOut.flush(); 
 
\t \t \t \t socketOut.println("Exitting..."); 
 
\t \t \t \t break loop; 
 
\t \t \t default: 
 
\t \t \t \t System.out.println("Unknown command!"); 
 
\t \t \t \t socketOut.println("Unknown command!"); 
 
\t \t \t \t break; 
 
\t \t \t } 
 
\t \t }while(command!=0); 
 
\t \t System.out.println("Closing connection to the client!"); 
 
\t \t }catch (IOException e){ 
 
\t \t \t e.printStackTrace(); 
 
\t \t }finally{ 
 
\t \t   try{ 
 
\t \t   if (socketIn!=null) socketIn.close(); 
 
\t \t   if (socketOut!=null) socketOut.close(); 
 
\t \t   if (connection!=null) connection.close(); 
 
\t \t   System.out.println("Connection to server closed!"); 
 
\t \t   } 
 
\t \t   catch(IOException e){ 
 
\t \t   System.err.println("Could not close connection!"); 
 
\t \t   } 
 
\t } 
 
\t \t try{ 
 
\t \t \t if(stmt != null) stmt.close(); 
 
\t \t \t if(resultSet != null) resultSet.close(); 
 
\t   if(link != null) link.close(); 
 
\t   System.out.println("Database connection closed successfully!"); 
 
\t \t }catch(SQLException ex){ 
 
\t \t \t System.out.println("Could not close connection to the database!"); 
 
\t \t } 
 
    } 
 
}

客戶端:

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 { 
 

 
\t public static void main(String[] args) { 
 
\t \t Socket connection = null; 
 
\t \t Scanner socketIn = null; 
 
\t \t DataOutputStream socketOut = null; 
 
\t \t int port = 1234; 
 
\t \t String host = "localhost"; 
 
\t \t Scanner keyIn = new Scanner(System.in); 
 
\t \t try{ 
 
\t \t \t try{ 
 
\t \t \t connection = new Socket(host,port); 
 
\t \t \t socketIn = new Scanner(new BufferedReader(new InputStreamReader(connection.getInputStream()))); 
 
\t \t \t socketOut = new DataOutputStream(connection.getOutputStream()); 
 
\t \t }catch(ConnectException e){ 
 
\t \t \t System.out.println("Could not connect to the host!"); 
 
\t \t \t return; 
 
\t \t } 
 
\t \t System.out.println("Successfully connected to the server!"); 
 
\t \t 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"); 
 
\t \t loop:do{ 
 
\t \t \t int command; 
 
\t \t \t socketOut.flush(); 
 
\t \t \t command = keyIn.nextInt(); 
 
\t \t \t socketOut.flush(); 
 
\t \t \t socketOut.writeInt(command); 
 
\t \t \t while (socketIn.hasNext()){ 
 
\t \t \t \t System.out.println(socketIn.nextLine()); 
 
\t \t \t } 
 
\t \t \t 
 
\t \t }while(keyIn.nextInt()!=0); 
 
\t \t System.out.println("Closing connection to server!"); 
 
\t }catch(IOException e){ 
 
\t \t e.printStackTrace(); 
 
\t } finally{ 
 
\t  try{ 
 
\t   if(socketIn!=null) socketIn.close(); 
 
\t   if(socketOut!=null) socketOut.close(); 
 
\t   if(connection!=null) connection.close(); 
 
\t   } 
 
\t   catch(IOException e){ 
 
\t   System.err.println("Socket could not be closed!"); 
 
\t   } 
 
\t  } 
 
\t \t 
 
\t } 
 
\t 
 
\t 
 
}

回答

0

的問題是,你在你的客戶使用Scanner。執行掛起socketIn.hasNext(),因爲

public boolean hasNext()

返回true,如果此掃描器的輸入中有另一個標記。此方法可能會在等待輸入進行掃描時阻塞。掃描儀不會超過任何輸入。

代碼會在有新輸入或底層流被關閉的情況下進行(我們不需要這樣做)。您必須有一種瞭解傳輸結束的方式,而不必關閉流。請看下面的非常簡單的一個。

在你的服務器的每try-catch block年底建成

socketOut.println("$$$"); 

在客戶端聲明socketInBufferedReader和實例爲

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); 

This也將修復您的雙重檢查keyIn.nextInt()。在你的代碼中,你每循環調用兩次(除了第一次迭代)。