簡體   English   中英

Java客戶端服務器/一個線程多個客戶端

[英]Java client-server / one thread multiple clients

首先,我不太確定如何在不引起混淆的情況下進行解釋,因此我將嘗試使其變得簡單。 我有一個服務器應用程序,可將兩個客戶端“配對”在一起,作為兩個玩家游戲的一部分。 發生的方式是,當第一個客戶端連接到服務器時,套接字連接被接受,並使用該客戶端創建了一個新的ClientProtocol線程,但未啟動。 當另一個客戶端連接到服務器時,他被添加到上一個線程,然后啟動該線程。 線程知道兩個輸入流和兩個輸出流,每個客戶端一個。 但是,當我嘗試從客戶端或服務器端讀取內容時,沒有任何反應。 對於單個線程中的單個客戶端,這工作正常。 這是一些代碼:

服務器端(主線程)

public static Queue<ContestProtocol> contesters;

public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = null;
    contesters = new LinkedList<ContestProtocol>();

    try {
        serverSocket = new ServerSocket(4444);
    } catch (IOException e) {
        System.err.println("Could not listen on port: 4444.");
        System.exit(-1);
    }

    while (true) {
        Socket socket = serverSocket.accept();

        ObjectInputStream ois;
        ObjectOutputStream oos;

        try {
            ois = new ObjectInputStream(socket.getInputStream());
            oos = new ObjectOutputStream(socket.getOutputStream());

            synchronized (contesters) {
                if (contesters.size() == 0) {
                    Contester contester1 = new contester(ois, oos);
                    contesters.add(new ContestProtocol(contester1));
                } else {
                    Contester contester2 = new Contester(ois, oos);
                    contesters.poll().hook(contester2).start();
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

服務器端(ContestProtocol)

private Contester contester1, contester2;

public ContestProtocol(Contester contester1) {
    super("ContestProtocol");
}

public ContestProtocol hook(Contester contester2) {
    this.contester2 = contester2;
    return this;
}

public void run() {
    try {
        contester1.getOOS().writeInt(-1);
        contester2.getOOS().writeInt(-2);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

服務器端(競賽者):

public Contester(ObjectInputStream ois, ObjectOutputStream oos) {
    this.ois = ois;
    this.oos = oos;
}

public ObjectInputStream getOIS() {
    return ois;
}

public ObjectOutputStream getOOS() {
    return oos;
}

客戶端:

try {
            socket = new Socket(serverAddr, 4444);
            oos = new ObjectOutputStream(socket.getOutputStream());
            ois = new ObjectInputStream(socket.getInputStream());
            int selectedChampion = ois.readInt();
} catch (Exception e) {
                e.printStackTrace();
}

ContestProtocol線程可以毫無問題地完成執行,但是兩個客戶端都掛在readInt()上。 我不理解為什么。

您應該循環您的客戶端輸入流。

while(true){
if(ois.avaible() > 0)
ois.readInt();
}

提示:研究使用netty的異步網絡以獲得更好的性能。

在訪問資源時,這必須要做互斥或信號量問題:您正在使用的流(在這種情況下是輸出流和輸入流)正試圖讀取和寫入同一資源。 因為所有這些進程都在一個連續線程上發生,所以它們的線程彼此中斷,並在另一個線程上創建等待進程。
一種解決方案是,您在流objecs上注冊事件標記,以便每當一個事件完成時,另一個便會啟動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM