반도체/MFC

[우주여행] 7장: C++ 네트워크 프로그래밍 - 소켓을 이용한 통신!

Clair_de_Lune 2024. 12. 17. 13:28
728x90

우주여행 7장 스타트!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 🌠🚀 형님, 이제 진짜 우주를 넘어서, C++의 네트워크 세계로 떠날 준비가 되셨나요?! 이제부터는 네트워크 프로그래밍을 배워보면서, 우주선들이 서로 통신하는 방식처럼, 컴퓨터들끼리도 서로 데이터를 주고받을 수 있는 방법을 익혀봅시다! 🌐✨

이번 장에서는 소켓 프로그래밍을 이용해서 네트워크를 통한 통신을 구현해보겠습니다! C++로 우주선들 간의 통신 시스템을 만들 수 있는 그날까지, 같이 가봅시다! 😎🔥


7장: C++ 네트워크 프로그래밍 - 소켓을 이용한 통신!

형님, 이제 C++로 네트워크를 통해 다른 컴퓨터와 데이터를 주고받을 수 있게 되었습니다! 네트워크 프로그래밍의 핵심은 바로 **소켓(socket)**을 사용하여 서버와 클라이언트 간의 통신을 처리하는 거예요! 🎉💻

1. 소켓(socket)이란 무엇인가?

소켓은 네트워크 통신을 위한 추상화된 인터페이스입니다. 클라이언트가 서버에 연결하거나, 서버가 클라이언트와 데이터를 주고받을 때 소켓을 사용해요! 🛰️

소켓을 사용하면:

  • 서버클라이언트IP 주소포트 번호를 통해 연결됩니다.
  • 소켓데이터 전송을 위한 통로 역할을 합니다!

우주선이 주파수를 맞춰 신호를 주고받는 것처럼, 소켓을 이용해 컴퓨터 간에 데이터를 송수신할 수 있는 거죠! 📡


2. 소켓 프로그래밍 기본 예시 - 클라이언트와 서버

형님, 이제 소켓을 사용해 간단한 서버와 클라이언트 프로그램을 만들어보겠습니다!

서버 프로그램 (Server)

서버는 클라이언트의 연결 요청을 기다리고, 연결이 오면 데이터를 주고받는 역할을 합니다!

#include <iostream>
#include <winsock2.h>  // 윈도우 소켓 프로그래밍에 필요한 헤더

#pragma comment(lib, "ws2_32.lib")  // 소켓 라이브러리 연결

int main() {
    WSADATA wsaData;
    SOCKET serverSocket, clientSocket;
    sockaddr_in serverAddr, clientAddr;
    int clientAddrSize = sizeof(clientAddr);

    // Winsock 초기화
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Winsock 초기화 실패!" << std::endl;
        return 1;
    }

    // 서버 소켓 생성
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "소켓 생성 실패!" << std::endl;
        WSACleanup();
        return 1;
    }

    // 서버 주소 설정
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;  // 모든 IP 주소에서 연결 허용
    serverAddr.sin_port = htons(8080);  // 포트 8080

    // 바인딩 (소켓에 IP와 포트를 할당)
    if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "바인딩 실패!" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    // 클라이언트 연결 대기
    listen(serverSocket, 3);
    std::cout << "클라이언트 연결 대기 중..." << std::endl;

    // 클라이언트 연결 수락
    clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrSize);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "클라이언트 연결 수락 실패!" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "클라이언트 연결 성공!" << std::endl;

    // 클라이언트에 메시지 전송
    const char* message = "안녕하세요, 클라이언트님!";
    send(clientSocket, message, strlen(message), 0);

    // 소켓 닫기
    closesocket(clientSocket);
    closesocket(serverSocket);
    WSACleanup();

    return 0;
}

설명:

  • 서버소켓을 생성하고, IP 주소포트 번호를 설정하여 바인딩합니다.
  • 클라이언트가 연결하면, accept 함수로 연결을 수락하고, 연결된 클라이언트에게 데이터를 전송합니다! ✉️

클라이언트 프로그램 (Client)

클라이언트는 서버에 연결하고, 서버로부터 데이터를 수신하는 역할을 합니다!

#include <iostream>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")  // 소켓 라이브러리 연결

int main() {
    WSADATA wsaData;
    SOCKET clientSocket;
    sockaddr_in serverAddr;
    char buffer[1024];

    // Winsock 초기화
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Winsock 초기화 실패!" << std::endl;
        return 1;
    }

    // 클라이언트 소켓 생성
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "소켓 생성 실패!" << std::endl;
        WSACleanup();
        return 1;
    }

    // 서버 주소 설정
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  // 서버 IP 주소 (자기 자신)
    serverAddr.sin_port = htons(8080);  // 포트 8080

    // 서버에 연결
    if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "서버 연결 실패!" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "서버에 연결되었습니다!" << std::endl;

    // 서버로부터 메시지 받기
    int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);
    if (bytesReceived == SOCKET_ERROR) {
        std::cerr << "데이터 수신 실패!" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    buffer[bytesReceived] = '\0';  // null terminator 추가
    std::cout << "서버로부터 받은 메시지: " << buffer << std::endl;

    // 소켓 닫기
    closesocket(clientSocket);
    WSACleanup();

    return 0;
}

설명:

  • 클라이언트서버 IP 주소포트 번호서버에 연결을 시도합니다.
  • 연결에 성공하면 서버로부터 데이터를 받고, 그 메시지를 출력합니다! 📨

3. 네트워크 통신의 핵심 포인트!

형님, 서버클라이언트 프로그램을 만들어보았어요! 이제 소켓을 사용하여 컴퓨터들 간의 데이터 전송을 어떻게 할 수 있는지 알게 되었죠! 네트워크 프로그래밍의 핵심은 소켓을 사용하여 클라이언트와 서버 간에 데이터를 주고받는 것입니다! 🌍✨

핵심 포인트!

  • 소켓서버와 클라이언트 간의 통신을 위한 통로입니다!
  • 서버는 클라이언트의 연결 요청을 수락하고, 데이터를 주고받을 수 있습니다!
  • 클라이언트서버에 연결하고, 서버로부터 데이터를 수신합니다!

7장의 마무리!

형님, 이제 C++ 네트워크 프로그래밍을 배우면서 소켓을 이용한 서버-클라이언트 통신을 구현할 수 있게 되었어요! 🌐🚀 이제 C++로 우주선들 간의 통신 시스템을 만들 준비가 되어 있죠! 😎

다음 시간에는 네트워크를 활용한 더 복잡한 통신데이터 송수신을 더욱 효율적으로 처리하는 방법을 배우게 될 거예요! 그때까지 네트워크 우주 여행을 위한 준비를 완료합시다! 🔥🌟

728x90