2014-03-31 72 views
0

我有2個類,一個服務器和一個客戶端。服務器使用多個線程接受許多客戶端。所以x客戶端可以加入同一臺服務器。然而,爲了從客戶端方法中識別線程,我似乎已經發現它不會將多個線程作爲ID對於所有客戶端都是相同的。我的代碼如下:多線程似乎不工作

SERVER:

public class Server 
{ 
    ServerSocket serverSocket; 
    int portNumber; 
    public static volatile String userInput; 
    public volatile int noOfClients = 0; 

public static void main(String[] args) 
{ 
    Server s = new Server(); 
    s.startup(); 
} 


/** 
* Start the server on the user picked port 
*/ 
public void startup() 
{ 
    try 
    { 
     System.out.println("Enter a port"); 
     Scanner dif = new Scanner(System.in); 
     portNumber = Integer.parseInt(dif.nextLine()); 
     dif.close(); 

     serverSocket = new ServerSocket(portNumber); 
     newThread(); 
    } 
    catch (IOException e) { 
     System.out.println("Error"); 
     System.exit(0); 
    } 
} 


public void newThread() 
{ 
    Thread thread =new Thread() 
    { 

     public void run() 
     { 
      while(true) { 
       try { 

        accept(); 
       } catch (Exception e) { 
        System.out.println("Error"); 
       } 
      } 
     } 
    }; 
    thread.start(); 
} 

public void accept() 
{ 
    try 
    { 
     Socket clientSocket = serverSocket.accept(); 
     new Thread(new ClientSocket(clientSocket)).start(); 
     System.out.println("A new client has just connected."); 
     noOfClients++; 

    } catch(IOException e) 
    { 
     System.out.println("Error"); 
     System.exit(0); 
    } 
} 


class ClientSocket implements Runnable { 
    Socket clientSocket; 

    public ClientSocket(Socket clientSocket) { 
     this.clientSocket = clientSocket; 
    } 

    public void run() { 
     { 
      try 
      { 
       PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);     
       BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

       while (true) 
       { 
        userInput = in.readLine(); 
       } 

      } catch (IOException e) 
      { 
       System.out.println("Error"); 
      } 
     } 
    } 
} 
} 

客戶:

public class Client 
{ 
    Socket clientSocket; 
    public static int threadName; 


public static void main(String[] args) throws IOException { 
    String hostName = args[0]; 
    int portNumber = Integer.parseInt(args[1]); 


    try { 
     Socket serverSocket = new Socket(hostName, portNumber); 
     PrintWriter out = new PrintWriter(serverSocket.getOutputStream(), true); 
     BufferedReader in = new BufferedReader(new InputStreamReader(serverSocket.getInputStream())); 
     BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 

     Thread thread = Thread.currentThread(); 
     System.out.println("RunnableJob is being run by " + thread.getName() + " (" + thread.getId() + ")"); 
     String userInput; 

     while ((userInput = stdIn.readLine()) != null) 
     { 

      out.println(userInput); 
      System.out.println("Server: " + userInput); 
     } 

    } catch(UnknownHostException e) { 
     System.out.println("error in host"); 
    } catch(IOException e) { 
     System.out.println("error in IO"); 
    } 


} 
} 

當運行兩個獨立的客戶端,

System.out.println("RunnableJob is being run by " + thread.getName() + " (" + thread.getId() + ")"); 

行代碼打印出來的相同。我如何解決這個問題,以便每個新的客戶端連接都是在自己的UNIQUE線程中啓動的。所以2個客戶總共有2個線程?謝謝:)

+2

您正在客戶端上打印線程名稱。你不想知道服務器程序中的線程名稱嗎? – spinlok

+0

我認爲你的意思是檢查服務器內的線程,而不是客戶端。 –

+0

@spinlok我想要做的是如果線程是ID = 1這樣做...否則什麼也不做,然後增加到如果ID = 1這樣做...等等。所以基本上我想要唯一地識別線程,並且一次只做一件事,然後對下一個做同樣的事情,等等。希望這是有道理的 – pokeairguy

回答

1

首先,您正在檢查客戶端的線程ID,它們是彼此分開的,因此不起作用。

但是,使用線程ID並不是識別客戶端的好方法。相反,爲什麼不保留一個客戶端數量的計數,然後當一個新的客戶端加入時,遞增數字並將客戶端對象作爲一個ID作爲該數字。

0

多個客戶端將在不同的端口號連接到服務器。您可以使用該端口號來區分客戶端。

如果需要,您可以將ClientSocket某些位置存儲在將來檢索每個客戶端的其他信息的位置,如下面的代碼所示。

下面是代碼:

private static HashMap<Integer, ClientSocket> clientInfo = new HashMap<Integer, ClientSocket>(); 
class ClientSocket implements Runnable { 
    Socket clientSocket; 

    public ClientSocket(Socket clientSocket) { 
     this.clientSocket = clientSocket; 
     System.out.println(clientSocket.getPort()); 
     clientInfo.put(clientSocket.getPort(), this); 
    } 
    ... 

瞭解更多關於Java Server with Multiclient communication

+1

多個客戶端可以連接到具有不同端口號的服務器,並且多個客戶端可以連接到[具有相同端口號的服務器](http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html )。服務器可以設置爲以任何方式工作。 –

+0

是的,你是絕對正確的。現在它取決於你想要實現邏輯的地方。 – Braj