본문 바로가기

C언어/개별프로그래밍

🖥️ Visual Studio에서 C 언어로 소켓 채팅 프로그램 만들기

반응형
SMALL

🌟 소켓 프로그래밍 소개

소켓 프로그래밍은 네트워크를 통해 데이터를 주고받는 프로그램을 만드는 기술이에요. 마치 전화기로 통화하는 것처럼, 컴퓨터들이 서로 대화할 수 있게 해주죠!

🛠️ Visual Studio 설정하기

  1. Visual Studio를 열어주세요.
  2. '새 프로젝트' → 'Windows 콘솔 애플리케이션'을 선택하세요.
  3. 프로젝트 이름을 정해주세요 (예: MyChatProgram).
  4. 프로젝트 속성 → 링커 → 입력 → 추가 종속성에 ws2_32.lib를 추가하세요.

👨‍💻 서버 코드 작성하기

서버는 손님을 기다리는 레스토랑 직원과 같아요. 손님(클라이언트)이 오면 대화를 시작하죠.

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {
    WSADATA wsa;
    SOCKET server_socket, client_socket;
    struct sockaddr_in server, client;
    char buffer[1024];
    int client_size, recv_size;

    // Winsock 초기화
    printf("Winsock 초기화 중...\n");
    if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) {
        printf("초기화 실패. 에러 코드 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("초기화 완료!\n");

    // 소켓 생성
    if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        printf("소켓 생성 실패 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("소켓 생성 완료!\n");

    // 서버 정보 설정
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(8888);

    // 바인딩
    if (bind(server_socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) {
        printf("바인딩 실패. 에러 코드 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("바인딩 완료!\n");

    // 리스닝
    listen(server_socket, 3);

    // 클라이언트 연결 대기
    printf("클라이언트 연결을 기다리는 중...\n");
    client_size = sizeof(struct sockaddr_in);
    client_socket = accept(server_socket, (struct sockaddr *)&client, &client_size);
    if (client_socket == INVALID_SOCKET) {
        printf("연결 수락 실패. 에러 코드 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("클라이언트 연결됨!\n");

    // 메시지 주고받기
    while ((recv_size = recv(client_socket, buffer, 1024, 0)) != SOCKET_ERROR) {
        buffer[recv_size] = '\0';
        printf("클라이언트: %s\n", buffer);
        send(client_socket, buffer, recv_size, 0);
    }

    // 정리
    closesocket(server_socket);
    WSACleanup();
    return 0;
}

👥 클라이언트 코드 작성하기

클라이언트는 레스토랑에 방문한 손님과 같아요. 서버에 연결하고 대화를 시작하죠.

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {
    WSADATA wsa;
    SOCKET sock;
    struct sockaddr_in server;
    char message[1024], server_reply[1024];
    int recv_size;

    // Winsock 초기화
    printf("Winsock 초기화 중...\n");
    if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) {
        printf("초기화 실패. 에러 코드 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("초기화 완료!\n");

    // 소켓 생성
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        printf("소켓 생성 실패 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("소켓 생성 완료!\n");

    // 서버 정보 설정
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(8888);

    // 서버에 연결
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
        printf("연결 실패. 에러 코드 : %d\n", WSAGetLastError());
        return 1;
    }
    printf("서버에 연결됨!\n");

    // 메시지 주고받기
    while (1) {
        printf("메시지 입력: ");
        gets(message);

        if (send(sock, message, strlen(message), 0) < 0) {
            printf("전송 실패\n");
            return 1;
        }

        if ((recv_size = recv(sock, server_reply, 1024, 0)) == SOCKET_ERROR) {
            printf("수신 실패\n");
            break;
        }

        server_reply[recv_size] = '\0';
        printf("서버 응답: %s\n", server_reply);
    }

    // 정리
    closesocket(sock);
    WSACleanup();
    return 0;
}

🚀 실행 및 테스트

  1. 서버 코드를 실행하세요.
  2. 새 콘솔 창을 열고 클라이언트 코드를 실행하세요.
  3. 클라이언트에서 메시지를 입력하고 서버의 응답을 확인하세요.

💡 팁과 주의사항

  • 서버는 항상 클라이언트보다 먼저 실행해야 해요.
  • 127.0.0.1은 로컬호스트 주소예요. 실제 네트워크에서는 서버의 실제 IP 주소를 사용해야 해요.
  • 보안을 위해 입력값 검증, 암호화 등의 추가 작업이 필요해요.
  • 실제 애플리케이션에서는 에러 처리를 더 강화해야 해요.

이제 여러분만의 채팅 프로그램을 만들 수 있어요! 🎉 추가 기능을 넣어 더 멋진 프로그램으로 발전시켜 보세요!

반응형
LIST