123

12·2026년 3월 13일

프로젝트데모

목록 보기
1/1

자바로 구현한다면 P2P 구조 + TCP + 멀티스레드로 설계하면 됩니다.
요구사항을 기준으로 실제로 구현 가능한 수준의 아키텍처를 보여줄게요. 💻

요구사항 다시 정리:

  • TCP 기반
  • 1:1 채팅
  • 서버/클라이언트 구분 없음
  • 하나의 exe(또는 jar)
  • CLI 프로그램
  • 채팅중이지 않은 사용자 선택

1️⃣ 전체 아키텍처

                ┌─────────────────────┐
                │     ChatProgram     │
                └─────────┬───────────┘
                          │
        ┌─────────────────┼─────────────────┐
        │                 │                 │
  ConnectionManager   PeerManager      CLIManager
        │                 │                 │
        │                 │                 │
   ┌────┴────┐        ┌───┴────┐       ┌────┴────┐
   │Listener  │        │PeerList│       │Command  │
   │Connector │        │Status  │       │Input    │
   └────┬────┘        └───┬────┘       └────┬────┘
        │                 │                 │
        └────────── MessageManager ─────────┘

각 모듈 역할 설명 👇


2️⃣ 핵심 클래스 구조

📌 Main

프로그램 시작점

public class Main {
    public static void main(String[] args) {
        ChatNode node = new ChatNode(5000);
        node.start();
    }
}

📌 ChatNode

프로그램 전체를 관리하는 핵심 클래스

class ChatNode {

    private ConnectionManager connectionManager;
    private PeerManager peerManager;
    private CLIManager cliManager;

    public ChatNode(int port) {
        connectionManager = new ConnectionManager(port);
        peerManager = new PeerManager();
        cliManager = new CLIManager(peerManager, connectionManager);
    }

    public void start() {
        connectionManager.startListening();
        cliManager.start();
    }
}

3️⃣ ConnectionManager (TCP 연결 관리)

역할

  • 다른 컴퓨터 연결
  • 연결 요청 수락
  • 소켓 관리
class ConnectionManager {

    private ServerSocket serverSocket;
    private List<Socket> connections = new ArrayList<>();

    public ConnectionManager(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    public void startListening() {
        new Thread(() -> {
            while(true) {
                try {
                    Socket socket = serverSocket.accept();
                    connections.add(socket);
                    new Thread(new MessageReceiver(socket)).start();
                } catch(Exception e) {}
            }
        }).start();
    }

    public void connectTo(String ip, int port) throws IOException {
        Socket socket = new Socket(ip, port);
        connections.add(socket);
        new Thread(new MessageReceiver(socket)).start();
    }
}

4️⃣ PeerManager (사용자 관리)

요구사항 핵심:

채팅중이지 않은 사람 선택

그래서 상태 관리 필요

class Peer {

    String name;
    Socket socket;
    boolean chatting;

}

관리 클래스

class PeerManager {

    private Map<String, Peer> peers = new HashMap<>();

    public void addPeer(String name, Socket socket) {
        peers.put(name, new Peer(name, socket, false));
    }

    public List<Peer> getIdlePeers() {
        return peers.values()
                .stream()
                .filter(p -> !p.chatting)
                .toList();
    }
}

5️⃣ MessageReceiver (메시지 수신)

각 연결마다 하나의 스레드

class MessageReceiver implements Runnable {

    private Socket socket;

    public MessageReceiver(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            BufferedReader reader =
                new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));

            String msg;

            while((msg = reader.readLine()) != null) {
                System.out.println("Received: " + msg);
            }

        } catch(Exception e) {}
    }
}

6️⃣ CLIManager (CLI 인터페이스)

사용자 입력 처리

class CLIManager {

    private Scanner scanner = new Scanner(System.in);
    private PeerManager peerManager;
    private ConnectionManager connectionManager;

    public CLIManager(PeerManager pm, ConnectionManager cm) {
        peerManager = pm;
        connectionManager = cm;
    }

    public void start() {

        while(true) {

            System.out.println("1. Connect");
            System.out.println("2. Show Users");
            System.out.println("3. Chat");

            int cmd = scanner.nextInt();

            if(cmd == 1) {

                System.out.print("IP: ");
                String ip = scanner.next();

                connectionManager.connectTo(ip, 5000);

            }

        }

    }
}

7️⃣ 메시지 프로토콜

단순 문자열 대신 프로토콜을 만드는 것이 좋습니다.

예:

HELLO|username
CHAT_REQUEST|username
CHAT_ACCEPT|username
CHAT_MESSAGE|username|message
CHAT_END|username

예시

CHAT_MESSAGE|Alice|Hello

8️⃣ 스레드 구조

프로그램 내부

Main Thread
   │
   ├─ CLI Thread
   │
   ├─ Server Listener Thread
   │
   └─ Connection Threads
        ├─ Peer A Receiver
        ├─ Peer B Receiver
        └─ Peer C Receiver

9️⃣ 실제 실행 예시

프로그램 실행

컴퓨터 A

java -jar chat.jar

컴퓨터 B

java -jar chat.jar

A에서

1. Connect
IP: 192.168.0.15

연결 성공

Users
1. Bob

채팅 시작

Chat with Bob >

🔟 exe / jar 만들기

jar

jar cfe chat.jar Main *.class

exe (선택)

  • Launch4j
  • jpackage

⭐ 이 프로젝트에서 가장 어려운 부분

실제로 학생들이 막히는 부분:

1️⃣ 동시 입력 + 메시지 출력 충돌
2️⃣ 채팅 상태 관리
3️⃣ 여러 연결 관리
4️⃣ 메시지 프로토콜 설계


💡 원하면 내가 다음도 보여줄게:

  • 이 프로젝트 실제 구현 코드 (~600줄짜리 구조)
  • P2P 채팅에서 가장 깔끔한 Java 구조
  • 같은 Wi-Fi 사용자 자동 탐색 (UDP broadcast) ← 교수들이 좋아하는 기능
  • CLI 채팅 UI 깔끔하게 만드는 방법

특히 자동 사용자 발견 기능까지 넣으면 이 프로젝트 퀄리티가 과제 수준 → 제대로 된 네트워크 프로그램 수준으로 올라갑니다.

0개의 댓글