[英]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.