まず第一に私はそれをどのように混乱させることなく説明するかわからないので、簡単にしようとします。私は2人のゲームの一環として2人のクライアントを一緒に「ペアにする」サーバーアプリケーションを持っています。方法は、最初のクライアントがサーバーに接続し、ソケット接続が受け入れられ、そのクライアントで新しいClientProtocolスレッドが作成され、開始されていないことです。別のクライアントがサーバーに接続すると、前のスレッドに追加され、スレッドが開始されます。スレッドは、クライアントごとに1つずつ、2つの入力ストリームと2つの出力ストリームを認識します。しかし、クライアント側またはサーバー側から読み取ろうとすると何も起こりません。これは、単一のスレッド内の単一のクライアントでうまく動作します。ここではいくつかのコードは次のとおりです。Javaクライアント/サーバ/ 1つのスレッド複数のクライアント
サーバー側(メインスレッド)
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();
}
}
サーバ側(contester):
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()でハングします。私はなぜなのか理解していない。
私はあなたがこれに近づいているのが好きかどうかはわかりませんが、それにもかかわらず、2人のクライアントはそれらのintを取得する必要があります。 Wiresharkは何を言いますか?サーバーからデータが出ていますか? –
いくつかのテストの後、いくつかのスレッドが互いにブロックしているように見えます。 ois.available()の呼び出しはデバッガで停止します。 – Renaud
ああ、私は仕事をしないようにあなたのデザインをエキスパートしましたが、ちょっとしたことがあっても、クライアントは何らかの読み取り呼び出しでサーバーがロックされる前にintを取得していたはずです。 –