우선 무엇보다 혼란스럽지 않고 설명하는 방법이 너무 명확하지 않으므로 간단하게하려고 노력할 것입니다. 2 명의 플레이어 게임의 일부로 2 명의 클라이언트를 "쌍으로"묶는 서버 응용 프로그램이 있습니다. 첫 번째 클라이언트가 서버에 연결될 때 소켓 연결이 수락되면 해당 클라이언트와 함께 새 ClientProtocol 스레드가 만들어 지지만 시작되지는 않습니다. 다른 클라이언트가 서버에 연결하면 이전 스레드에 추가되고 스레드가 시작됩니다. 스레드는 두 개의 입력 스트림과 두 개의 출력 스트림 (각 클라이언트에 하나씩)을 알고 있습니다. 그러나 클라이언트 또는 서버 측에서 읽으려고하면 아무 일도 일어나지 않습니다. 이것은 단일 스레드에서 단일 클라이언트에 대해 잘 작동합니다.Java 클라이언트 - 서버/하나의 스레드 다중 클라이언트
서버 측 (메인 스레드)
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()에서 중단됩니다. 나는 왜 그런지 이해하지 못한다.
내가 접근하는 방식이 마음에 드는지 모르겠지만 그럼에도 불구하고 두 고객이 그 int를 얻어야합니다. Wireshark는 무엇이라고 말합니까? 서버에서 데이터가 빠져 나오고 있습니까? –
일부 테스트 후에 일부 스레드가 서로를 차단해야하는 것으로 보입니다. ois.available()에 대한 호출이 디버거에서 중단됩니다. – Renaud
오, 나는 작동하지 않도록 디자인을 exepcted하지만 네드웨어없이 클라이언트가 서버를 읽기 전에 잠글 때까지 int를 가져야합니다. –