버전: 1.0
작성일: 2025년 6월 16일
본 프로젝트는 TCP/IP 소켓 통신 기반의 다중 사용자 실시간 그림 퀴즈 게임입니다.
서버와 클라이언트는 C언어로 각각 구현되었으며, 클라이언트는 SDL2 그래픽 라이브러리를 사용해 직관적인 GUI를 제공합니다.
💡 이 프로젝트는 소켓 프로그래밍, 동시성 처리, 커스텀 프로토콜 설계를 실습하는 데 목적이 있습니다.
- 단일 스레드로 수많은 클라이언트를 효율적으로 감시 및 처리
select()시스템 콜로 이벤트가 발생한 소켓만 처리- 스레드/프로세스를 남발하지 않기에 자원 소비가 적고 안정적
- 메인 스레드: SDL UI 렌더링 및 사용자 입력 처리
- 수신 스레드: 서버로부터 메시지 수신 (UI 블로킹 방지)
- OS: Linux (Ubuntu, CentOS 등)
- 컴파일러:
gcc - 필수 라이브러리:
pthreads,libsdl2-dev,libsdl2-ttf-dev
sudo apt-get update
sudo apt-get install build-essential libsdl2-dev libsdl2-ttf-dev
## 4. 🎮 주요 기능 설명
### 4.1. ✅ 다중 클라이언트 & 안정성
- 최대 `FD_SETSIZE` (기본 1024명)까지 이론적으로 동시 접속 지원
- 클라이언트의 비정상 종료를 감지하고, 소켓 및 상태 정리를 자동 수행
- TCP의 스트림 특성을 보완하기 위해 개행 문자(`\n`) 기준으로 메시지를 분리하는 **메시지 프레이밍(Message Framing)** 로직 구현
### 4.2. 🏠 방 기반 게임 관리
- 명령어 `/create`, `/join`, `/roomlist`, `/exit` 등을 통해 방 생성 및 입장
- 서버는 각 방의 고유 상태(유저 목록, 정답, 출제자 등)를 유지 관리
### 4.3. 🎯 출제자 검증 및 턴 제어
- `drawer_sock` 값으로 출제자 여부를 판단
- `DRAW_`, `SET_ANSWER` 명령은 출제자인지 확인 후에만 처리
- 출제자 외 사용자의 무단 입력 방지
### 4.4. ⏰ 제한 시간 기반 라운드
- 각 라운드는 기본 60초로 제한
- 시간이 만료되면 정답 공개 후, 다음 출제자로 턴 자동 전환
### 4.5. 📚 문제은행 및 정답 처리
- `word_list`를 통해 중복 없는 단어 출제
- 정답자가 등장하면 해당 클라이언트를 다음 출제자로 자동 지정
---
## 5. 💬 사용자 명령어 요약
| 명령어 | 인자 | 설명 |
|-----------|------------|----------------------------------------|
| `/nick` | `<닉네임>` | 닉네임 설정 |
| `/create` | `<방이름>` | 방 생성 후 입장 |
| `/join` | `<방ID>` | 지정된 방에 입장 |
| `/roomlist` | 없음 | 현재 생성된 방 목록 조회 |
| `/exit` | 없음 | 현재 참여 중인 방에서 나가기 |
| `/answer` | `<단어>` | (출제자 전용) 현재 라운드의 정답 단어 설정 |
| `/guess` | `<단어>` | (참가자 전용) 정답 추측 |
| `/quit` | 없음 | 클라이언트 종료 |
| *(없음)* | `<메시지>` | 현재 방 참여자에게 채팅 메시지 전송 |
------------------------------------------------------------------
## 6. 🛰️ 통신 프로토콜 명세
### 📤 클라이언트 → 서버
NICK:<nickname>
CREATE_ROOM:<room_name>
JOIN_ROOM:<room_id>
LIST_ROOMS
EXIT_ROOM
SET_ANSWER:<word>
GUESS:<word>
DRAW_POINT:<x>,<y>,<color_idx>,<size>
DRAW_LINE:<x1>,<y1>,<x2>,<y2>,<color_idx>,<size>
DRAW_CLEAR
MSG:<chat_message>
QUIT
### 📥 서버 → 클라이언트
SMSG:<server_message> // 시스템 메시지
ROOM_EVENT:<event_message> // 방 내 이벤트 (입장, 퇴장 등)
MSG:[nickname] <chat_message> // 일반 채팅 메시지
TURN_CHANGED:<drawer_nickname> // 출제자 변경 알림
DRAW_POINT:... / DRAW_LINE:... // 그림판 그리기 데이터