2014-02-24 84 views
2

我已經使用JAVA中的套接字編程編寫了一個基本的服務器客戶端程序。該服務器是多線程的,可以一次接受多個客戶端連接。但客戶端不是多線程的。客戶端可以從服務器上傳,下載,讀取,寫入和刪除文件。我在命令提示符窗口中運行這些程序,以便它們沒有任何外部用戶界面。到目前爲止,我的程序工作正常。可以同時連接到多個服務器的客戶端程序

我現在想讓客戶端多線程以及它可以同時連接到多個服務器。然後我希望客戶端能夠向服務器發送請求。客戶端可以選擇要將請求發送到可能連接的許多服務器中的哪個服務器。

考慮到這一點,我改變了客戶端代碼有多個線程。但我不知道如何在程序運行時在服務器之間進行選擇。有沒有辦法在JAVA中(在程序運行時)隨意切換線程,以便我可以選擇哪個線程處理我的請求?

+0

那麼你打算每臺客戶端連接到一個服務器?您可以爲每個線程分配一個處理請求的阻塞隊列,並讓用戶線程將作業放入這些隊列中。但沒有理由你需要每個服務器的線程;您只需要儘可能多的線程來執行同時運算符,因此如果只有一個操作可以選擇服務器,則不需要多個線程。或者,您可以在執行程序池中有少量線程來執行對您的服務器連接集的操作。 – Rup

+0

如果我將客戶端連接到三臺服務器,那麼客戶端自動至少需要三個線程? – 1xQ

+0

不一定,儘管在實踐中它可能取決於您使用的協議以及您發佈的操作可能會阻塞多長時間。沒有理由說單個線程不能監視許多TCP連接,並且對它們進行異步響應。但每個客戶端連接的線程可以正常工作,並且(通常)線程便宜。 – Rup

回答

4

這是某種形式的骨架,你怎麼能做到這一點的:

public class Client { 

    public static void main(String[] args) { 

     Connection w1 = new Connection("localhost", 2346); 
     w1.start(); 

     Connection w2 = new Connection("localhost", 2346); 
     w2.start(); 

     Connection w3 = new Connection("localhost", 2347); 
     w3.start(); 

     w1.sendMessage("Hello "); 
     w2.sendMessage("Coffee "); 
     w1.sendMessage("world!"); 
     w2.sendMessage("break!"); 
     w3.sendMessage("Beer!"); 

     w1.terminate(); 
     w2.terminate(); 
     w3.terminate(); 
    } 
} 

只要你不使用繁忙等待其確定處理在一個新的線程每連接:

import java.io.IOException; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.concurrent.ConcurrentLinkedQueue; 

public class Connection implements Runnable { 

    private String host; 
    private int port; 
    private PrintWriter os; 

    private volatile boolean running = false; 
    private ConcurrentLinkedQueue<String> queue; 

    public Connection(String host, int port) { 
     this.host = host; 
     this.port = port; 
     this.queue = new ConcurrentLinkedQueue<String>(); 
    }; 

    public void start() { 
     try { 
      this.os = new PrintWriter(new Socket(host, port).getOutputStream()); 
     } catch (IOException e) { 
      return; 
     } 

     running = true; 
     new Thread(this).start(); 
    } 

    @Override 
    public void run() { 

     while(running) { 
      // send messages in queue 
      while(!queue.isEmpty()) { 
       os.print(queue.poll()); 
      } 
      // wait to be notified about new messages 
      try { 
       this.wait(); 
      } catch (InterruptedException e) { 
       terminate(); 
      } 
     } 
    } 

    public synchronized void sendMessage(String msg) { 
     queue.add(msg); 
     this.notify(); 
    } 

    public void terminate() { 
     running = false; 
    } 

    public boolean isRunning() { 
     return running; 
    } 
} 
相關問題