[c++] libuv의 소켓 프로그래밍

libuv는 C++ 언어용 비동기 I/O 라이브러리로, 소켓 프로그래밍에 매우 유용하게 사용됩니다. 이 라이브러리를 사용하여 네트워크 통신을 비동기적으로 처리하고, 다중 클라이언트 연결을 관리할 수 있습니다. 이번 글에서는 libuv를 사용하여 C++로 소켓 프로그래밍을 하는 방법에 대해 알아봅니다.

libuv 라이브러리 설치

먼저 libuv 라이브러리를 설치해야 합니다. 이 라이브러리는 다양한 플랫폼에서 사용할 수 있으며, 간단한 명령어로 설치할 수 있습니다.

Windows에서 libuv 설치

Windows에서는 다음과 같은 명령어로 libuv를 설치할 수 있습니다.

npm install node-gyp -g
npm install libuv

MacOS 또는 Linux에서 libuv 설치

MacOS 나 Linux에서는 다음과 같은 명령어로 libuv를 설치할 수 있습니다.

brew install libuv

libuv를 사용한 C++ 소켓 프로그래밍 예제

이제 libuv를 사용하여 C++로 간단한 소켓 서버 및 클라이언트 프로그램을 작성해보겠습니다.

소켓 서버 프로그램 예제

#include <uv.h>
#include <iostream>

int main() {
    uv_loop_t* loop = uv_default_loop();

    struct sockaddr_in addr;
    uv_ip4_addr("0.0.0.0", 3000, &addr);

    uv_tcp_t server;
    uv_tcp_init(loop, &server);
    uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
    uv_listen((uv_stream_t*)&server, 128, [](uv_stream_t* server, int status) {
        if (status < 0) {
            std::cerr << "Error on listen" << std::endl;
        }
        uv_tcp_t* client = new uv_tcp_t;
        uv_tcp_init(uv_default_loop(), client);
        if (uv_accept(server, (uv_stream_t*)client) == 0) {
            uv_read_start((uv_stream_t*)client, [](uv_handle_t* client, size_t suggested_size, uv_buf_t* buf) {
                buf->base = new char[suggested_size];
                buf->len = suggested_size;
            }, [](uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) {
                if (nread < 0) {
                    uv_close((uv_handle_t*)client, [](uv_handle_t* handle) {
                        delete[] buf->base;
                        delete handle;
                    });
                } else if (nread > 0) {
                    std::cout << "Received data: " << std::string(buf->base, nread) << std::endl;
                }
            });
        } else {
            uv_close((uv_handle_t*)client, [](uv_handle_t* handle) {
                delete handle;
            });
        }
    });

    return uv_run(loop, UV_RUN_DEFAULT);
}

소켓 클라이언트 프로그램 예제

#include <uv.h>
#include <iostream>

int main() {
    uv_loop_t* loop = uv_default_loop();

    uv_tcp_t socket;
    uv_tcp_init(loop, &socket);

    struct sockaddr_in dest;
    uv_ip4_addr("127.0.0.1", 3000, &dest);

    uv_connect_t connect_req;
    uv_tcp_connect(&connect_req, &socket, (const struct sockaddr*)&dest, [](uv_connect_t* req, int status) {
        if (status < 0) {
            std::cerr << "Error on connect" << std::endl;
            return;
        }
        const char* data = "Hello, libuv!";
        uv_buf_t buf = uv_buf_init((char*)data, strlen(data));
        uv_write_t write_req;
        uv_write(&write_req, (uv_stream_t*)&socket, &buf, 1, [](uv_write_t* req, int status) {
            if (status < 0) {
                std::cerr << "Error on write" << std::endl;
            }
            uv_close((uv_handle_t*)req->handle, NULL);
        });
    });

    return uv_run(loop, UV_RUN_DEFAULT);
}

위의 소켓 서버 및 클라이언트 예제는 libuv 라이브러리를 사용하여 비동기 소켓 통신을 구현한 것입니다. libuv를 사용하여 C++로 소켓 프로그래밍을 할 때 위 예제를 참고해 보시기 바랍니다.

결론

libuv는 C++로 소켓 프로그래밍을 쉽게 할 수 있게 해주는 강력한 라이브러리입니다. 이 라이브러리를 사용하면 비동기적으로 네트워크 통신을 처리하고 다중 클라이언트를 관리할 수 있습니다. libuv를 사용한 C++ 소켓 프로그래밍은 효율적이고 확장 가능한 네트워크 애플리케이션을 개발하는 데 도움이 될 것입니다.

그럼 다들 libuv를 사용하여 C++로 소켓 프로그래밍을 시작해보세요!