2012-02-07 152 views
1

我的代碼存在問題。我使用Java等待連接的服務器。當客戶端連接時,如果我們(服務器)發送命令「showinfo」,則該客戶端將其IP地址發送回服務器。在JAVA的服務器/客戶端程序的解決方案

問題是它是一個多線程服務器和許多客戶端連接。因此,例如,如果2個客戶連接到服務器,我們必須輸入2次showinfo,然後客戶給我們提供信息。如何讓客戶端立即響應,爲每個客戶端輸入「showinfo」,並且不要等到我爲所有客戶端輸入showinfo。如果在執行命令之前有50個客戶端,則輸入50次showinfo會有點累。謝謝你在前進(我已經嘗試了一些線程同步和一些sleep()join()命令,但我還沒有得出結論,但我希望你能有點幫助。)

這裏的服務器代碼

import java.io.*; 
import java.net.*; 
import java.security.*; 

public class Server implements Runnable{ 
    private Socket server; 
    private static String command,info,message; 
    BufferedReader infromclient =null; 
    InputStream infromclient2=null; 
    DataOutputStream outtoclient =null; 
    static BufferedReader infrommaster=null; 
    private static int port=6789; 

    Server(Socket server){ 
     try{  
      this.server=server; 
      infromclient =new BufferedReader(new InputStreamReader(server.getInputStream())); 
      outtoclient =new DataOutputStream(server.getOutputStream()); 
      infrommaster=new BufferedReader(new InputStreamReader(System.in)); 
     }catch(IOException e){ 
      System.out.println("Exception accessing socket streams: "+e); 
     } 
    } 

    // main() 
    // Listen for incoming connections and handle them 
    public static void main(String[] args) { 
     ThreadGroup clients = new ThreadGroup("clients"); 
     System.out.print("Waiting for connections on port " + port + "..."); 
     System.out.println("\nIn total there are:"+clients.activeCount()+" clients\n"); 
     try{ 
      ServerSocket server = new ServerSocket(port); 
      Socket nextsocket; 

      // waiting for connections 
      while(true){ 
       nextsocket = server.accept(); 
       Thread client= new Thread(clients,new Server(nextsocket),"client"+(clients.activeCount()+1)); 
       System.out.println("Client connected"); 
       System.out.println("There are "+clients.activeCount()+" clients connected"); 
       client.start();         
      } 

     }catch (IOException ioe){ 
      System.out.println("IOException on socket listen: " + ioe); 
      ioe.printStackTrace(); 
     }  
    } 

    public void run(){     
     try{        
      command=infrommaster.readLine(); 
      outtoclient.writeBytes(command+"\n"); 

      // showinfo 
      if(command.equals("showinfo")){   
       info=infromclient.readLine(); 
       System.out.println("\nClient information\n\n" +info+"\n");      
      } 

      server.close();       
     }catch (IOException ioe){ 
      System.out.println("IOException on socket listen: " + ioe); 
      ioe.printStackTrace(); 
     }  
    } 
} 

,這裏是客戶端的代碼:

import java.io.*; 
import java.net.*; 
import java.lang.*; 


public class Client{ 

    public static void main(String args[]) throws Exception{ 
     String command2; 
     String info; 
     Socket clientSocket=null; 
     Socket scket=null;  
     BufferedReader inFromUser=null; 
     DataOutputStream outToServer=null; 
     BufferedReader inFromServer=null; 
     BufferedWriter tosite=null; 

     try{ 
      clientSocket = new Socket(InetAddress.getLocalHost().getHostName(), 6789); 
      inFromUser =new BufferedReader(new InputStreamReader(System.in)); 
      outToServer =new DataOutputStream(clientSocket.getOutputStream()); 
      inFromServer =new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));  
     }catch(UnknownHostException | IOException e){ 
      System.out.println("Problem "+e); 
     }       

     command2=inFromServer.readLine(); 
     System.out.println("From Server:" +command2); 

     // showinfo 
     if (command2.equals("showinfo")){ 
      try{ 
       InetAddress myip=InetAddress.getLocalHost(); 
       info =("IP: " +myip.getHostAddress()+"\n"); 

       System.out.println("\nSome system information\n" + info); 
       outToServer.writeBytes(info);   
      }catch (Exception e){ 
       System.out.println("Exception caught ="+e.getMessage()); 
      } 
     } 

     outToServer.flush(); 
     outToServer.close(); 
     inFromUser.close(); 
     inFromServer.close(); 
     clientSocket.close(); 
    } 
} 

**命令clientSocket = new Socket(InetAddress.getLocalHost().getHostName(), 6789);意味着它測試我的電腦(我在6789端口IP)。

回答

1

如果一條線程在readline上被阻塞,另一個線程最終應該得到控制權。這就是多線程的重點。我想我知道你的問題。相反,將您正在閱讀輸入命令的代碼移動到服務器的run()方法中。那你應該很好。我認爲問題在於您在輪詢輸入後開始線程啓動。

移動這些線路從服務器構造到服務器的run()方法:

infromclient =new BufferedReader(new InputStreamReader(server.getInputStream())); 
      outtoclient =new DataOutputStream(server.getOutputStream()); 
      infrommaster=new BufferedReader(new InputStreamReader(System.in)); 
+0

所以就像你說的,如果客戶端在服務器不發送的字符串信息如何可以發送它的IP? – user1195787 2012-02-07 21:56:18

+0

客戶端仍會發送它,但它不必從用戶那裏接收它。 – Sid 2012-02-08 02:38:39

+0

這個代碼是我製作的一個最大的項目的一小部分,服務器有必要給它的客戶端一些命令,這就是爲什麼用戶必須輸入。我嘗試了一些同步命令,但我成功的唯一的事情是讓其他線程等待最快,然後第二個等線程來結束它的操作。我只想問你,有沒有另一種方法,一個命令可能會使程序更具操作性?我也想過多任務/廣播,但我不知道很多事情。順便說一句,謝謝你的回答 – user1195787 2012-02-09 00:39:59