2014-02-22 21 views
1

給定兩個代碼,一個用於服務器,另一個用於客戶端,我試圖讓多個客戶端與服務器通信,但我不知道如何去做。任何想法服務器如何識別與他交談並回復給同一客戶的客戶?有多個客戶端的服務器 - JAVA

服務器:

import java.io.*; 
    import java.net.*; 
    public class Provider{ 
    ServerSocket providerSocket; 
    Socket connection = null; 
    ObjectOutputStream out; 
    ObjectInputStream in; 
    String message; 
    Provider(){} 
    void run() 
{ 
    try{ 
     //1. creating a server socket 
     providerSocket = new ServerSocket(2004, 10); 
     //2. Wait for connection 
     System.out.println("Waiting for connection"); 
     connection = providerSocket.accept(); 
     System.out.println("Connection received from " + connection.getInetAddress().getHostName()); 
     //3. get Input and Output streams 
     out = new ObjectOutputStream(connection.getOutputStream()); 
     out.flush(); 
     in = new ObjectInputStream(connection.getInputStream()); 
     sendMessage("Connection successful"); 

     //4. The two parts communicate via the input and output streams 
     do{ 
      try{ 
       message = (String)in.readObject(); 

       System.out.println("client>" + message); 
       if (message.equals("byee")) 
        sendMessage("Wosil"); 
      } 
      catch(ClassNotFoundException classnot){ 
       System.err.println("Data received in unknown format"); 
      } 
     }while(!message.equals("bye")); 
    } 
    catch(IOException ioException){ 
     ioException.printStackTrace(); 
    } 
    finally{ 
     //4: Closing connection 
     try{ 
      in.close(); 
      out.close(); 
      providerSocket.close(); 
     } 
     catch(IOException ioException){ 
      ioException.printStackTrace(); 
     } 
    } 
} 
void sendMessage(String msg) 
{ 
    try{ 
     out.writeObject(msg); 
     out.flush(); 
     System.out.println("Zame-Server>" + msg); 
    } 
    catch(IOException ioException){ 
     ioException.printStackTrace(); 
    } 
} 
public static void main(String args[]) 
{ 
    Provider server = new Provider(); 
    while(true){ 
     server.run(); 
     } 
    } 
} 

客戶

import java.io.*; 
import java.net.*; 
public class Requester{ 
Socket requestSocket; 
ObjectOutputStream out; 
ObjectInputStream in; 
String message; 
Requester(){} 
void run() 
{ 
    try{ 
     //1. creating a socket to connect to the server 
     requestSocket = new Socket("localhost", 2004); 
     System.out.println("Connected to localhost in port 2004"); 
     //2. get Input and Output streams 
     out = new ObjectOutputStream(requestSocket.getOutputStream()); 
     out.flush(); 
     in = new ObjectInputStream(requestSocket.getInputStream()); 
     //3: Communicating with the server 

       sendMessage("Hi my server"); 
       sendMessage("SENDING"); 
       message = "byee"; 
       sendMessage(message); 
     do{ 
      try{ 
       message = (String)in.readObject(); 
       System.out.println("server>" + message); 


      } 
      catch(ClassNotFoundException classNot){ 
       System.err.println("data received in unknown format"); 
      } 
     }while(!message.equals("bye")); 
    } 
    catch(UnknownHostException unknownHost){ 
     System.err.println("You are trying to connect to an unknown host!"); 
    } 
    catch(IOException ioException){ 
     ioException.printStackTrace(); 
    } 
    finally{ 
     //4: Closing connection 
     try{ 
      in.close(); 
      out.close(); 
      requestSocket.close(); 
     } 
     catch(IOException ioException){ 
      ioException.printStackTrace(); 
     } 
    } 
} 
void sendMessage(String msg) 
{ 
    try{ 
     out.writeObject(msg); 
     out.flush(); 
     System.out.println("Zame-Client>" + msg); 
    } 
    catch(IOException ioException){ 
     ioException.printStackTrace(); 
    } 
} 
public static void main(String args[]) 
{ 
    Requester client = new Requester(); 
    client.run(); 
} 
} 
+1

該插座是雙向的。您可以從中獲取OutputStream和InputStream,以便您可以發送和接收數據。你只需要記住flush()數據。但服務器阻塞等待連接,並會拒絕其他連接,除非您提供新的套接字。您需要在單獨的線程中處理每個套接字以同時支持多個客戶端。看看Executors類(java.util.concurrent)。 – helderdarocha

+0

歡迎來到Stack Overflow!請注意,標籤獨立。也就是說,你不能合併多個標籤來創建一個概念。標籤'[client]'和'[server]'與單個'[client-server]'標籤不一樣。請務必閱讀選擇標籤時出現的說明! – Charles

回答

2

你的問題似乎有兩面。第一個涉及併發(如何啓動多個客戶端並使它們與服務器通信)。爲此,您必須具備Java中線程的基本知識。您的問題的第二部分:服務器如何跟蹤多個客戶端(這也表明您的客戶端和服務器之間的通信是有狀態的):您可能想要設計一個簡單的協議,通過該協議客戶端和服務器通信。例如,當客戶端與服務器進行通信時,它必須使用唯一標識符來標記其消息。服務器使用該標識符來跟蹤並保持它用來完成任務的任何資源,客戶端詢問它(如果這完全由您的要求來規定的話)。

+0

你是100%正確的,我在兩年前把java作爲大學的一門課程,我們沒有把重點放在客戶端 - 服務器上,你提到了威脅和ID,我會研究這些。如果您有任何可以幫助我的網站,我將不勝感激,謝謝 – Zame

+0

您的第一個資源應該是oracle的[併發文檔](http://docs.oracle.com/javase/tutorial/essential/concurrency/),因爲oracle是Java語言的當前設計者/維護者。之後,谷歌是你的朋友。例如這裏有一個[教程](http://tutorials.jenkov。com/java-concurrency/creating-and-starting-threads.html)我想,在向你介紹一些小步驟的併發性的同時,解釋一些應該知道的常見事情。 – ylabidi

2

不知道如果我正確理解你的問題,但我想你想多個客戶端與服務器同時通信。要做到這一點,你需要知道如何使用線程。當服務器連接到客戶端時,該連接必須在它自己的線程中運行。那麼它將準備好接受新的客戶端連接。如果你正確地做到這一點,你將能夠運行一次服務器,並有許多客戶端連接到服務器。

1

Kryonet是一個非常好的Java庫,它爲使用NIO進行高效的TCP和UDP客戶端/服務器網絡通信提供了一個乾淨而簡單的API。

這將使您的網絡編程工作變得更容易,您可以更好地瞭解如何編寫客戶端和服務器端代碼。

我建議你嘗試使用這個庫的網絡編程技巧。

你甚至不需要在LAN中硬編碼服務器的IP地址。客戶端只需一行代碼即可發現服務器。

相關問題