💡 멀티 쓰레드 기반 채팅 서버 구현 (소켓 프로그래밍)
오늘은 멀티 쓰레드 기반의 채팅 서버를 직접 구현해 보았습니다.
소켓을 이용해 서버와 클라이언트가 통신하며, 여러 사용자가 동시에 접속할 수 있도록 설계했습니다. 또한, 메시지 전송뿐만 아니라 닉네임 변경, 귓속말, 이미지 전송, 채팅 기록 저장 등의 기능도 추가했습니다.
🛠️ 사용 기술
- Java (소켓 프로그래밍, 멀티 쓰레드, 파일 입출력)
- ConcurrentHashMap (멀티쓰레드 환경에서 동기화된 데이터 관리)
- InputStream / OutputStream (데이터 송수신)
- UUID (고유 ID 생성)
- File API (이미지 저장 및 불러오기)
📌 채팅 서버 구조 및 기능
🔹 ChatServer.java (서버)
- ServerSocket 을 이용해 클라이언트 접속을 대기
- 멀티 쓰레드 처리로 여러 클라이언트 동시 접속 가능
- ConcurrentHashMap 으로 클라이언트 정보 관리
- 전체 메시지 전송, 귓속말, 닉네임 변경, 이미지 저장/불러오기 기능 포함
public class ChatServer {
ServerSocket serverSocket;
Map<String, ClientService> chatClientInfo = new ConcurrentHashMap<>();
Map<String, byte[]> imageStore = new ConcurrentHashMap<>();
public void start(int portNo) {
try {
serverSocket = new ServerSocket(portNo);
System.out.println("[채팅서버] 시작");
} catch (IOException e) {
e.printStackTrace();
}
}
public void connectClient() {
new Thread(() -> {
try {
while (true) {
Socket socket = serverSocket.accept();
new ClientService(this, socket);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
🔹 ChatClient.java (클라이언트)
- 서버에 접속 후 메시지를 주고받음
- 실시간 메시지 수신 (새로운 쓰레드로 처리)
- 닉네임 변경, 귓속말, 이미지 전송 등 다양한 기능 제공
public class ChatClient {
Socket socket;
DataInputStream dis;
DataOutputStream dos;
public void connect(String serverIP, int portNo, String chatName) {
try {
socket = new Socket(serverIP, portNo);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
send(chatName);
} catch (IOException e) {
System.out.println("서버 연결 실패");
}
}
}
🔹 ClientService.java (클라이언트 개별 처리)
- 각 클라이언트별 개별 스레드 실행
- 닉네임 관리, 메시지 송수신, 귓속말, 이미지 전송 기능 포함
public class ClientService {
ChatServer chatServer;
Socket socket;
DataInputStream dis;
DataOutputStream dos;
String chatName;
public ClientService(ChatServer chatServer, Socket socket) throws IOException {
this.chatServer = chatServer;
this.socket = socket;
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
while (true) {
chatName = dis.readUTF();
if (chatServer.isChatNameUnique(chatName)) {
chatServer.addClientInfo(this);
break;
} else {
send("닉네임 중복, 다른 이름을 입력하세요");
}
}
}
}
📌 오늘 공부하면서 어려웠던 점
- 멀티 쓰레드 동기화 문제 🚀
- 여러 클라이언트가 동시에 접속하면 데이터 충돌이 발생할 가능성이 높음
- 해결 방법: synchronized 키워드와 ConcurrentHashMap 사용
- 이미지 전송 처리 🖼️
- 파일을 byte[]로 변환 후 전송해야 함
- 파일 크기 정보도 함께 전송해야 정상적으로 수신 가능
🔥 개선할 부분
- 클라이언트 UI 추가 🎨
- 현재는 콘솔에서 채팅을 주고받지만, Swing 또는 JavaFX로 GUI를 추가하면 사용자 경험이 개선될 것 같음
- 데이터베이스 연동 🗄️
- 현재는 서버 메모리에 사용자 정보를 저장하는데, MySQL, MongoDB 같은 DB와 연결하면 더욱 안정적인 시스템이 될 것
🎥 추가 학습 자료
더 자세한 설명과 실습 영상은 유튜브 우코딩AI에서 확인할 수 있습니다!
👉 유튜브 우코딩AI
✅ 오늘의 결론
✔ 소켓 프로그래밍을 이용한 멀티 쓰레드 채팅 서버 구현 성공!
✔ 서버-클라이언트 간 메시지 송수신 및 다양한 기능 추가
✔ 멀티쓰레드 동기화와 파일 전송 방법 학습 완료
✔ 앞으로 GUI 개선 및 데이터베이스 연동 도전 예정! 🚀
'My HomePage (board project)' 카테고리의 다른 글
7회차 : Bank Application 프로젝트 학습 정리 (2025년 1월 28일) (0) | 2025.01.28 |
---|---|
6회차 : 댓글과 대댓글 구현 공부 일지 (2025년 1월 22일) (0) | 2025.01.22 |
5회차 : 티스토리 블로그: 목록 페이징 구현 공부 기록 (2025-01-21) (1) | 2025.01.22 |
2025-01-20 : 카카오 로그인 구현 정리 (0) | 2025.01.20 |
Woo Do Yeon의 개발자 홈페이지 업그레이드 (1) | 2025.01.20 |