Skip to content

Instantly share code, notes, and snippets.

@kYroL01
Forked from teraPacket/tcp_client.c
Created February 17, 2021 11:08
Show Gist options
  • Save kYroL01/84f7a18c6077dd1db7a586fc99e42274 to your computer and use it in GitHub Desktop.
Save kYroL01/84f7a18c6077dd1db7a586fc99e42274 to your computer and use it in GitHub Desktop.

Revisions

  1. @teraPacket teraPacket created this gist Aug 16, 2017.
    91 changes: 91 additions & 0 deletions tcp_client.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    #include <stdio.h>
    #include <stdlib.h>
    #include <uv.h>

    //based on https://gist.github.com/snatchev/5255976/
    //raw/8392c42d719bb775053036e32b21affdf932c1b7/libuv-tcp-client.c
    //which was based on libuv 0.1, there is considerable difference there.
    static void on_close(uv_handle_t* handle);
    static void on_connect(uv_connect_t* req, int status);
    static void on_write(uv_write_t* req, int status);

    static uv_loop_t *loop;

    static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
    *buf = uv_buf_init(malloc(size), size);
    }

    void on_close(uv_handle_t* handle)
    {
    printf("closed.");
    }

    void on_write(uv_write_t* req, int status)
    {
    if (status) {
    perror( "uv_write error ");
    return;
    }
    printf("wrote.\n");
    free(req);
    //uv_close((uv_handle_t*)req->handle, on_close);
    }

    void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf)
    {
    printf("on_read. %p\n",tcp);
    if(nread >= 0) {
    //printf("read: %s\n", tcp->data);
    printf("read: %s\n", buf->base);
    }
    else {
    //we got an EOF
    uv_close((uv_handle_t*)tcp, on_close);
    }

    //cargo-culted
    free(buf->base);
    }

    void write2(uv_stream_t* stream, char *data, int len2) {
    uv_buf_t buffer[] = {
    {.base = data, .len = len2}
    };
    uv_write_t *req = malloc(sizeof(uv_write_t));
    uv_write(req, stream, buffer, 1, on_write);
    }

    void on_connect(uv_connect_t* connection, int status)
    {
    if (status < 0) {
    printf("failed to connect\n"); return;
    }
    printf("connected. %p %d\n",connection, status);

    uv_stream_t* stream = connection->handle;
    free(connection);
    write2(stream, "echo world!", 12);
    uv_read_start(stream, alloc_cb, on_read);
    }

    void startConn(char *host, int port) {
    uv_tcp_t *pSock = malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, pSock);
    uv_tcp_keepalive(pSock, 1, 60);

    struct sockaddr_in dest;
    uv_ip4_addr(host, port, &dest);

    uv_connect_t *pConn = malloc(sizeof(uv_connect_t));
    printf("allocated %p\n", pConn);
    uv_tcp_connect(pConn, pSock, (const struct sockaddr*)&dest, on_connect);
    }

    int main(int argc, char **argv) {
    loop = uv_default_loop();
    int i;
    for (i=0; i<10; i++)
    startConn("127.0.0.1", 80);

    uv_run(loop, UV_RUN_DEFAULT);
    }