본문 바로가기
Project/socket_chat_server

[CPP] 소켓 통신 채팅 서버 만들기 - 기본 기능 구현하기 - client

by 블로블로글 2024. 3. 18.

client 코드도 마찬가지로 따라하면서 분석하며 공부를 진행했다. 아래는 코드를 참고한 블로그의 주소이다.

https://a-researcher.tistory.com/122

 

[c++] TCP/IP 서버 클라이언트 설명 및 예제 코드 (소켓 프로그래밍)

TCP(전송 제어 프로토콜)는 두 컴퓨터 간의 안정적인 통신을 설정하는 데 사용됩니다. TCP 서버와 클라이언트 코드를 통해 두 컴퓨터 간의 데이터를 전송할 수 있습니다. 이 문서에서는 C++로 작성

a-researcher.tistory.com

우선 클라이언트도 서버와 마찬가지로 통신을 위한 소켓을 생성해야한다.

socket(AF_INET, SOCK_STREAM, 0)

서버와 마찬가지로 IPv4 프로토콜, TCP, 기본 프로토콜을 사용하는 소켓을 생성 한다.

 

 

int inet_pton(int af, const char *src, void *dst);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);

af

  - 주소 체계를 지정하며, AF_INET(IPv4), AF_INET(IPv6)를 지원함

src

  - 바이너리 형식으로 변환될 IP 주소의 문자열

dst

  - 변환된 네트워크 주소를 저장할 메모리

 

이 함수를 통해 IP 주소를 텍스트 형식에서 네트워크 바이트 순서로 변환하여 소켓이 이해할 수 있는 형태로 지정

 

 

connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

sock

  - 소켓 파일 디스크립터

(struct sockaddr *)&serv_addr

  - 서버의 주소 정보를 담고 있는 구조체의 주소

sizeof(serv_addr)

  - 서버 주소 구조체의 크기입니다.

 

클라이언트 소켓을 서버의 주소에 지정된 포트로 연결, 이 과정을 통해 TCP 연결이 설정되고 이후에는 데이터를 주고 받는 등의 함수가 들어가게됨. 앞선 글에서 설명했듯이 서버-클라이언트 간의 간단한 메시지를 주고 받는 프로그램이므로 이후에는 간단한 read, send등의 함수가 들어간다.

 

전체 코드

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#define PORT 3000

using namespace std;

int main(int argc, char const *argv[]) {
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    const char* hello = "Hello from client";
    char buffer[1024] = {0};

    // Create socket file descriptor
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        cerr << "Socket creation error" << endl;
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Convert IPv4 and IPv6 addresses from text to binary form
    // ipv4와 ipv6 주소를 텍스트에서 바이너리 형태로 변환
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
        cerr << "Invalid address/ Address not supported" << endl;
        return -1;
    }

    // Connect to the server
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection failed");
        cerr << "Connection Failed" << endl;
        return -1;
    }

    // Send message to the server
    send(sock, hello, strlen(hello), 0);
    cout << "Hello message sent" << endl;

    // Receive message from the server
    valread = read(sock, buffer, 1024);
    cout << buffer << endl;

    return 0;
}

이로써 클라이언트 - 서버 프로그램이 모두 완성되었고 실행해보면 성공적을 클라이언트와 서버가 통신을 주고 받는 것을 알 수 있다.

위 그림과 같은 구조의 통신을 그대로 구현되었음 을 확인할 수 있고, 기본을 다지기 정말 좋은 코드였다.