2016-02-13 61 views
4

我已經使用java(多線程)實現了客戶界面。在客戶端,客戶端在服務器已經運行時登錄。多個客戶端可以登錄爲每個客戶端創建一個線程。我想實現的是當多個客戶端登錄時我想在服務器控制檯(eclipse)中輸入一個命令,該命令列出了在控制檯上輸入內容後登錄的所有客戶端。如何在客戶端服務器程序中從服務器控制檯獲取輸入

客戶方的代碼:代碼

btnLogin.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       // TODO Auto-generated method stub 
       Connection conn = null; 
       try // try block 
       { 
        // declare variables 
        String username = ""; 
        String pwd = ""; 

        // get values using getText() method 
        username = loginEmail.getText().trim(); 
        pwd = new String(loginPassword.getPassword()); 

        // check condition it field equals to blank throw error 
        // message 
        if (username.equals("") || pwd.equals("")) { 
         JOptionPane.showMessageDialog(null, " name or password or Role is wrong", "Error", 
           JOptionPane.ERROR_MESSAGE); 
        } else // else insert query is run properly 
        { 
         String IQuery = "select accountnumber, customername, address from `customeraccount` where emailaddress=? and password=?"; 
         String accnum = null; 
         System.out.println("Connecting to a selected database..."); 

         // STEP 3: Open a connection 
         conn = DriverManager.getConnection(DB_URL, user_name, password); 
         System.out.println("Connected database successfully..."); 
         PreparedStatement stmt = conn.prepareStatement(IQuery); 
         stmt.setString(1, username); 
         stmt.setString(2, pwd); 
         ResultSet rs = stmt.executeQuery(); 
         while (rs.next()) { 
          detailName.setText(rs.getString("customername")); 
          detailAddress.setText(rs.getString("address")); 
          accnum = rs.getString("accountnumber"); 
         } 
         out.println(accnum); 
         out.println(detailName.getText()); 
         rs.close(); 
         ((java.sql.Connection) conn).close(); 
        } 
       } catch (SQLException se) { 
        // handle errors for JDBC 

        se.printStackTrace(); 
       } catch (Exception a) // catch block 
       { 
        a.printStackTrace(); 
       } 
      } 
     }); 

服務器端:

public class StoreServer { 
static ArrayList<String[]> list2 = new ArrayList<String[]>(); 

public static void main(String[] args) throws IOException { 
    System.out.println("The server is running."); 
    int clientNumber = 0; 
    ServerSocket listener = new ServerSocket(3355); 

    try { 
     while (true) { 
      new Thread(new Customer(listener.accept(), clientNumber++)).start(); 
     } 
    } finally { 
     listener.close(); 
    } 
} 

private static class Customer implements Runnable { 
    private Socket socket; 
    private int clientNumber; 

    public Customer(Socket socket, int clientNumber) { 
     this.socket = socket; 
     this.clientNumber = clientNumber; 
     // log("New connection with client# " + clientNumber + " at " + 
     // socket); 
    } 

    /** 
    * Services this thread's client by first sending the client a welcome 
    * message then repeatedly reading strings and sending back the 
    * capitalized version of the string. 
    */ 
    public void run() { 
     try { 

      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 


      while (true) { 

        System.out.println("Account Number: " + acnum + " Name: " + name); 
       if (acnum == null || acnum.equals(".")) { 
        break; 
       } 
       // out.println(input.toUpperCase()); 
      } 
     } catch (IOException e) { 
      log("Error handling client# " + clientNumber + ": " + e); 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       log("Couldn't close a socket, what's going on?"); 
      } 
      // log("Connection with client# " + clientNumber + " closed"); 
     } 
    }}} 

回答

6

這是你想要的片段:

private static class CommandListener implements Runnable { 

    @Override 
    public void run() { 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     while(true) { 
      try { 
       String command = br.readLine(); 
       if(command.equals("listClients")) { 

        // Assuming you will have static list of customer. In which you will 
        // add a customer/client when a new client get connected and remove 
        // when a client get disconnected 

        System.out.println("Total Connected customer :" + customers.size()); 
        System.out.println("Details :"); 
        for(Customer cust : customers) { 
         System.out.println(cust.getName()); 
        } 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

在你StoreServer類創建CommandListener類的一個對象,只是監聽服務器端口之前將它傳遞給一個線程。像這樣的:

public class StoreServer { 

    static ArrayList<String[]> list2 = new ArrayList<String[]>(); 
    static List<Customer> customers = new LinkedList<Customer>(); 

    public static void main(String[] args) throws IOException { 
     System.out.println("The server is running."); 
     int clientNumber = 0; 
     ServerSocket listener = new ServerSocket(3355); 
     Thread commandListenerThread = new Thread(new CommandListener()); 
     commandListenerThread.start(); 
     try { 
      while (true) { 
       Socket socket = listener.accept(); 
       Customer cust = new Customer(socket, clientNumber++); 
       customers.add(cust); 
       new Thread(cust).start(); 
      } 
     } finally { 
      listener.close(); 
     } 
    ..... 

請注意,這只是一個片段,而不是一個適當和優化的代碼。除此之外,還有很多可以在你發佈的代碼中完成的改進,比如在線程創建邏輯等方面保留一個閾值。但是我忽略了這一點,因爲你的問題只涉及在Server程序中從控制檯獲取輸入。

+0

我認爲它是最合適的答案。謝謝Sumit。 –

+0

@human此代碼段是否幫助您? –

1

開始聽傳入插座之前,你應該開始一個新的線程。在這個線程中,你可以讀取System.in中的行。 (用InputStreamReader包裝System.in,然後用BufferedReader)。現在,當您從控制檯讀取某個命令時,您可以打印出有關連接客戶端的信息。

+0

謝謝你。將嘗試 – human