
문제: 다중 접속 불가
기본 Echo 서버는 단일 클라이언트와만 통신 가능
서버가 한 명 상대하는 동안 다른 사람은 접속 불가
➡ 멀티스레딩 구조로 확장해야 해결 가능
접속자 들어올 때마다 대화용 스레드 인스턴스를 생성하자! (for 멀티태스킹)
public class ServerThread extends Thread {
GUIServer guiServer;
Socket socket;
BufferedReader buffr; // 수신 스트림
BufferedWriter buffw; // 발신 스트림
// 접속자가 들어올 때마다 소켓을 서버로부터 전달받기
public ServerThread(GUIServer guiServer, Socket socket) {
this.guiServer = guiServer;
this.socket = socket;
// 접속과 동시에 스트림 얻어놓기
try {
buffr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
buffw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
// 클라이언트로부터 메시지 수신 → 서버 GUI에 출력 → 다시 클라이언트에게 전송
public void receive() {
String msg = null;
try {
msg = buffr.readLine(); // 수신
guiServer.area.append(msg + "\n"); // 서버 GUI에 출력
send(msg); // 클라이언트에게 다시 전송 (에코)
} catch (IOException e) {
e.printStackTrace();
}
}
// 메시지 클라이언트에게 전송
public void send(String msg) {
try {
buffw.write(msg + "\n");
buffw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
// 스레드 실행: 메시지 계속 수신 대기
@Override
public void run() {
while (true) {
receive();
}
}
}
// 사용자가 접속할 때마다, 몇 명이 현재 서버를 사용 중인지,
// 그 기록을 처리할 객체
Vector<ServerThread> vec = new Vector<>();
Vector는 동기화(synchronized)가 보장되는 컬렉션이기 때문에,
여러 스레드가 동시에 접근해도 안전하게 처리할 수 있어서 사용함!
...
public void startServer() {
try {
// 입력한 포트 번호로 서버소켓 생성
server = new ServerSocket(Integer.parseInt(t_port.getText()));
while (true) {
area.append("서버 생성 및 접속자 청취 중....\n");
// 클라이언트 접속 대기 → 접속되면 socket 반환
Socket socket = server.accept();
area.append(socket.getInetAddress().getHostAddress() + " 님 접속 \n");
// 🔹 접속자 1명당 대화용 스레드 인스턴스 생성 → 소켓 전달 (for 멀티태스킹)
ServerThread st = new ServerThread(this, socket);
st.start(); // 스레드 시작
// 접속자 목록에 추가 (벡터에 저장)
vec.add(st);
area.append("현재 접속자 " + vec.size() + "명\n");
}
} catch (NumberFormatException | IOException e) {
e.printStackTrace();
}
}
무한 반복문은 서버가 항상 열려 있고,
새로운 클라이언트의 접속을 기다리는 상태를 유지하게 함그리고 그 동안 접속자가 들어올 때마다 그때그때 새 스레드를 만들어주는 구조
기본 Echo 서버는 1:1 통신(Unicasting) 방식이므로,
다수의 사용자가 동시에 통신하기 위해서는
접속자마다 스레드를 할당하는 멀티스레딩 구조로 확장해야 한다.