Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Linux C/C++ Socket Programming by Example: TCP/UDP Chat, select, Threads, Timers, and fork

Tech 2

TCP Chat over a Local Network

Minimal TCP Echo Server (C)

#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define PORT 7000

int main(void) {
    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_fd < 0) {
        perror("socket");
        return 1;
    }

    int opt = 1;
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    struct sockaddr_in srv;
    memset(&srv, 0, sizeof(srv));
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = htonl(INADDR_ANY);
    srv.sin_port = htons(PORT);

    if (bind(listen_fd, (struct sockaddr *)&srv, sizeof(srv)) < 0) {
        perror("bind");
        return 1;
    }

    if (listen(listen_fd, 20) < 0) {
        perror("listen");
        return 1;
    }

    struct sockaddr_in cli;
    socklen_t cli_len = sizeof(cli);
    int conn_fd = accept(listen_fd, (struct sockaddr *)&cli, &cli_len);
    if (conn_fd < 0) {
        perror("accept");
        return 1;
    }

    char buf[1024];
    for (;;) {
        ssize_t n = recv(conn_fd, buf, sizeof(buf), 0);
        if (n <= 0) break;
        if (n == 5 && memcmp(buf, "exit\n", 5) == 0) break;
        fwrite(buf, 1, n, stdout);
        send(conn_fd, buf, n, 0);
    }

    close(conn_fd);
    close(listen_fd);
    return 0;
}

Minimal TCP Client (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 7000
#define BUFSZ 1024

int main(void) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return 1;
    }

    struct sockaddr_in srv;
    memset(&srv, 0, sizeof(srv));
    srv.sin_family = AF_INET;
    srv.sin_port = htons(PORT);
    srv.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(fd, (struct sockaddr *)&srv, sizeof(srv)) < 0) {
        perror("connect");
        return 1;
    }

    char sendbuf[BUFSZ];
    char recvbuf[BUFSZ];

    while (fgets(sendbuf, sizeof(sendbuf), stdin)) {
        send(fd, sendbuf, strlen(sendbuf), 0);
        if (strcmp(sendbuf, "exit\n") == 0) break;
        ssize_t n = recv(fd, recvbuf, sizeof(recvbuf) - 1, 0);
        if (n <= 0) break;
        recvbuf[n] = '\0';
        fputs(recvbuf, stdout);
    }

    close(fd);
    return 0;
}

Bidirectional Asynchronous Chat with select

TCP Server with Non-blocking Console and Socket (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define PORT 7000

int main(void) {
    int srv_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (srv_fd < 0) { perror("socket"); return 1; }

    int yes = 1;
    setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    struct sockaddr_in sa;
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
    sa.sin_port = htons(PORT);

    if (bind(srv_fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }
    if (listen(srv_fd, 20) < 0) { perror("listen"); return 1; }

    struct sockaddr_in ca; socklen_t ca_len = sizeof(ca);
    int cli_fd = accept(srv_fd, (struct sockaddr *)&ca, &ca_len);
    if (cli_fd < 0) { perror("accept"); return 1; }

    for (;;) {
        fd_set rs; FD_ZERO(&rs);
        FD_SET(STDIN_FILENO, &rs);
        FD_SET(cli_fd, &rs);
        int hi = cli_fd > STDIN_FILENO ? cli_fd : STDIN_FILENO;

        struct timeval to = {5, 0};
        int rc = select(hi + 1, &rs, NULL, NULL, &to);
        if (rc < 0) { perror("select"); break; }
        if (rc == 0) continue;

        if (FD_ISSET(cli_fd, &rs)) {
            char b[1024];
            ssize_t n = recv(cli_fd, b, sizeof(b) - 1, 0);
            if (n <= 0) break;
            b[n] = '\0';
            if (strcmp(b, "exit\n") == 0) break;
            fputs(b, stdout);
        }
        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char line[1024];
            if (!fgets(line, sizeof(line), stdin)) break;
            send(cli_fd, line, strlen(line), 0);
        }
    }

    close(cli_fd);
    close(srv_fd);
    return 0;
}

TCP Client with select (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 7000
#define BUFSZ 1024

int main(void) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) { perror("socket"); return 1; }

    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_port = htons(PORT);
    sa.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("connect"); return 1; }

    for (;;) {
        fd_set rs; FD_ZERO(&rs);
        FD_SET(STDIN_FILENO, &rs); FD_SET(fd, &rs);
        int hi = fd > STDIN_FILENO ? fd : STDIN_FILENO;
        struct timeval to = {5, 0};
        int rc = select(hi + 1, &rs, NULL, NULL, &to);
        if (rc < 0) { perror("select"); break; }
        if (rc == 0) continue;

        if (FD_ISSET(fd, &rs)) {
            char r[BUFSZ]; ssize_t n = recv(fd, r, sizeof(r) - 1, 0);
            if (n <= 0) break; r[n] = '\0'; fputs(r, stdout);
        }
        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char s[BUFSZ]; if (!fgets(s, sizeof(s), stdin)) break;
            send(fd, s, strlen(s), 0);
        }
    }

    close(fd);
    return 0;
}

Broadcast Chat to a Fixed Number of Clients

Server acepting two clients and boradcasting console input (C++)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>

#include <cstring>
#include <iostream>
#include <thread>
#include <vector>

#define PORT 7000

static int listen_fd;
static int clients[2] = {-1, -1};
static int ccount = 0;

void accept_one() {
    struct sockaddr_in ca; socklen_t cl = sizeof(ca);
    int fd = accept(listen_fd, (struct sockaddr *)&ca, &cl);
    if (fd < 0) { perror("accept"); exit(1); }
    if (ccount < 2) clients[ccount++] = fd;
}

int main() {
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    int yes = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    sockaddr_in sa{}; sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(PORT);
    if (bind(listen_fd, (sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }
    if (listen(listen_fd, 8) < 0) { perror("listen"); return 1; }

    std::thread t1(accept_one);
    std::thread t2(accept_one);
    t1.join(); t2.join();

    for (;;) {
        fd_set rs; FD_ZERO(&rs); FD_SET(STDIN_FILENO, &rs);
        int hi = STDIN_FILENO;
        for (int i = 0; i < ccount; ++i) {
            if (clients[i] >= 0) { FD_SET(clients[i], &rs); if (clients[i] > hi) hi = clients[i]; }
        }
        struct timeval to{5,0};
        int rc = select(hi + 1, &rs, NULL, NULL, &to);
        if (rc <= 0) continue;

        for (int i = 0; i < ccount; ++i) {
            if (clients[i] >= 0 && FD_ISSET(clients[i], &rs)) {
                char b[1024]; ssize_t n = recv(clients[i], b, sizeof(b) - 1, 0);
                if (n <= 0) { close(clients[i]); clients[i] = -1; }
                else { b[n] = '\0'; std::cout << b; }
            }
        }
        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char line[1024]; if (!fgets(line, sizeof(line), stdin)) break;
            for (int i = 0; i < ccount; ++i) if (clients[i] >= 0) send(clients[i], line, strlen(line), 0);
        }
    }

    for (int i = 0; i < ccount; ++i) if (clients[i] >= 0) close(clients[i]);
    close(listen_fd);
    return 0;
}

Matching Client (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 7000
#define BUFSZ 1024

int main(void) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_port = htons(PORT); sa.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("connect"); return 1; }

    for (;;) {
        fd_set rs; FD_ZERO(&rs); FD_SET(STDIN_FILENO, &rs); FD_SET(fd, &rs);
        int hi = fd > STDIN_FILENO ? fd : STDIN_FILENO;
        struct timeval to = {5, 0};
        int rc = select(hi + 1, &rs, NULL, NULL, &to); if (rc <= 0) continue;

        if (FD_ISSET(fd, &rs)) {
            char r[BUFSZ]; ssize_t n = recv(fd, r, sizeof(r) - 1, 0);
            if (n <= 0) break; r[n] = '\0'; fputs(r, stdout);
        }
        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char s[BUFSZ]; if (!fgets(s, sizeof(s), stdin)) break; send(fd, s, strlen(s), 0);
        }
    }

    close(fd);
    return 0;
}

Scaalble Broadcast Server (unbounded clients) using select

Server (C++)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>

#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>

#define PORT 7000

int main() {
    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    int yes = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    sockaddr_in sa{}; sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(PORT);
    if (bind(listen_fd, (sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }
    if (listen(listen_fd, 64) < 0) { perror("listen"); return 1; }

    std::vector<int> peers;

    for (;;) {
        fd_set rs; FD_ZERO(&rs);
        FD_SET(listen_fd, &rs); FD_SET(STDIN_FILENO, &rs);
        int hi = std::max(listen_fd, STDIN_FILENO);
        for (int fd : peers) { FD_SET(fd, &rs); if (fd > hi) hi = fd; }

        struct timeval to{2, 0};
        int rc = select(hi + 1, &rs, NULL, NULL, &to);
        if (rc < 0) { perror("select"); break; }
        if (rc == 0) continue;

        if (FD_ISSET(listen_fd, &rs)) {
            sockaddr_in ca{}; socklen_t cl = sizeof(ca);
            int cfd = accept(listen_fd, (sockaddr *)&ca, &cl);
            if (cfd >= 0) peers.push_back(cfd);
        }

        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char line[1024]; if (fgets(line, sizeof(line), stdin)) {
                for (int fd : peers) send(fd, line, strlen(line), 0);
            }
        }

        for (size_t i = 0; i < peers.size(); ) {
            int fd = peers[i];
            if (FD_ISSET(fd, &rs)) {
                char b[1024]; ssize_t n = recv(fd, b, sizeof(b) - 1, 0);
                if (n <= 0) { close(fd); peers.erase(peers.begin() + i); continue; }
                b[n] = '\0'; std::cout << b; // server displays client messages
            }
            ++i;
        }
    }

    for (int fd : peers) close(fd);
    close(listen_fd);
    return 0;
}

Client (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 7000
#define BUFSZ 1024

int main(void) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_port = htons(PORT); sa.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("connect"); return 1; }

    for (;;) {
        fd_set rs; FD_ZERO(&rs); FD_SET(STDIN_FILENO, &rs); FD_SET(fd, &rs);
        int hi = fd > STDIN_FILENO ? fd : STDIN_FILENO;
        struct timeval to = {5, 0};
        int rc = select(hi + 1, &rs, NULL, NULL, &to); if (rc <= 0) continue;

        if (FD_ISSET(fd, &rs)) {
            char r[BUFSZ]; ssize_t n = recv(fd, r, sizeof(r) - 1, 0);
            if (n <= 0) break; r[n] = '\0'; fputs(r, stdout);
        }
        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char s[BUFSZ]; if (!fgets(s, sizeof(s), stdin)) break; send(fd, s, strlen(s), 0);
        }
    }

    close(fd);
    return 0;
}

UDP Echo

UDP Server (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 8888
#define BUFSZ 256

int main(void) {
    int s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) { perror("socket"); return 1; }

    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_port = htons(PORT); sa.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }

    for (;;) {
        char buf[BUFSZ];
        struct sockaddr_in ca; socklen_t cl = sizeof(ca);
        ssize_t n = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&ca, &cl);
        if (n < 0) continue;
        fwrite(buf, 1, n, stdout);
        sendto(s, buf, n, 0, (struct sockaddr *)&ca, cl);
    }
}

UDP Client (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 8888
#define BUFSZ 256

int main(int argc, char **argv) {
    if (argc != 2) { fprintf(stderr, "usage: %s <server-ip>\n", argv[0]); return 1; }
    int s = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_port = htons(PORT);
    if (inet_pton(AF_INET, argv[1], &sa.sin_addr) != 1) { perror("inet_pton"); return 1; }

    char line[BUFSZ];
    for (;;) {
        if (!fgets(line, sizeof(line), stdin)) break;
        sendto(s, line, strlen(line), 0, (struct sockaddr *)&sa, sizeof(sa));
        char r[BUFSZ]; socklen_t sl = sizeof(sa);
        ssize_t n = recvfrom(s, r, sizeof(r) - 1, 0, (struct sockaddr *)&sa, &sl);
        if (n > 0) { r[n] = '\0'; fputs(r, stdout); }
    }

    close(s);
    return 0;
}

Process and System Utilities

Get Current PID and Parenet PID (C)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
    printf("pid=%d ppid=%d\n", (int)getpid(), (int)getppid());
    return 0;
}

Invoke a Shell Command with system (C)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int rc = system("uname -a");
    printf("system() returned %d\n", rc);
    return 0;
}

Timers

Periodic timer via setitimer + SIGALRM (C)

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

static volatile int ticks = 0;

static void on_alarm(int sig) {
    (void)sig;
    printf("tick %d\n", ++ticks);
}

int main(void) {
    struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = on_alarm;
    sigaction(SIGALRM, &sa, NULL);

    struct itimerval iv; memset(&iv, 0, sizeof(iv));
    iv.it_value.tv_sec = 1;      // first fire
    iv.it_interval.tv_sec = 1;   // interval
    setitimer(ITIMER_REAL, &iv, NULL);

    for (;;) pause();
}

Sleep in milliseconds using select timeout (C)

#include <sys/select.h>

static void sleep_ms(unsigned int ms) {
    struct timeval tv;
    tv.tv_sec = ms / 1000;
    tv.tv_usec = (ms % 1000) * 1000;
    select(0, NULL, NULL, NULL, &tv);
}

select Basics

Wait for stdin with timeout (C)

#include <stdio.h>
#include <string.h>
#include <sys/select.h>
#include <unistd.h>

int main(void) {
    for (;;) {
        fd_set rs; FD_ZERO(&rs); FD_SET(STDIN_FILENO, &rs);
        struct timeval to = {5, 0};
        int rc = select(STDIN_FILENO + 1, &rs, NULL, NULL, &to);
        if (rc < 0) { perror("select"); break; }
        if (rc == 0) { puts("timeout"); continue; }
        if (FD_ISSET(STDIN_FILENO, &rs)) {
            char line[1024];
            if (!fgets(line, sizeof(line), stdin)) break;
            fputs(line, stdout);
        }
    }
    return 0;
}

POSIX Threads

Create a thread and pass an argument (C)

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct { int value; } args_t;

static void *worker(void *p) {
    args_t *a = (args_t *)p;
    printf("worker: value=%d\n", a->value);
    return NULL;
}

int main(void) {
    pthread_t th;
    args_t a = { .value = 42 };
    if (pthread_create(&th, NULL, worker, &a) != 0) {
        perror("pthread_create");
        return 1;
    }
    printf("main thread\n");
    pthread_join(th, NULL);
    return 0;
}

Network Interface Info

Read MAC from sysfs and IP via ioctl (C)

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>

static int read_mac_sysfs(const char *ifname, char mac[18]) {
    char path[256]; snprintf(path, sizeof(path), "/sys/class/net/%s/address", ifname);
    FILE *f = fopen(path, "r"); if (!f) return -1;
    size_t n = fread(mac, 1, 17, f); mac[(n < 17) ? n : 17] = '\0'; fclose(f);
    return 0;
}

static int get_ip_ioctl(const char *ifname, struct in_addr *ip) {
    int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) return -1;
    struct ifreq ifr; memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
    if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { close(s); return -1; }
    *ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
    close(s); return 0;
}

int main(int argc, char **argv) {
    if (argc != 2) { fprintf(stderr, "usage: %s <iface>\n", argv[0]); return 1; }
    char mac[18] = {0};
    if (read_mac_sysfs(argv[1], mac) == 0) printf("MAC: %s\n", mac);
    struct in_addr ip; if (get_ip_ioctl(argv[1], &ip) == 0) printf("IP : %s\n", inet_ntoa(ip));
    return 0;
}

Processes and fork

Basic fork example (C)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
    pid_t p = fork();
    if (p < 0) {
        perror("fork");
    } else if (p == 0) {
        printf("child: pid=%d ppid=%d\n", (int)getpid(), (int)getppid());
    } else {
        printf("parent: pid=%d child=%d\n", (int)getpid(), (int)p);
    }
    return 0;
}

Concurrent TCP Server using fork (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define PORT 6000
#define BUFSZ 2048

static void reap(int) { while (waitpid(-1, NULL, WNOHANG) > 0) {} }

int main(void) {
    signal(SIGCHLD, reap);

    int lf = socket(AF_INET, SOCK_STREAM, 0);
    int yes = 1; setsockopt(lf, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(PORT);
    if (bind(lf, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }
    if (listen(lf, 64) < 0) { perror("listen"); return 1; }

    for (;;) {
        struct sockaddr_in ca; socklen_t cl = sizeof(ca);
        int c = accept(lf, (struct sockaddr *)&ca, &cl);
        if (c < 0) { perror("accept"); continue; }
        pid_t pid = fork();
        if (pid < 0) { perror("fork"); close(c); continue; }
        if (pid == 0) { // child
            close(lf);
            char b[BUFSZ];
            for (;;) {
                ssize_t n = read(c, b, sizeof(b) - 1);
                if (n <= 0) break;
                b[n] = '\0';
                printf("%s", b);
            }
            close(c);
            _exit(0);
        } else {
            close(c);
        }
    }
}

Simple TCP Client to the forked server (C)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 6000
#define BUFSZ 2048

int main(int argc, char **argv) {
    if (argc != 2) { fprintf(stderr, "usage: %s <server-ip>\n", argv[0]); return 1; }

    int fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in sa; memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET; sa.sin_port = htons(PORT);
    if (inet_pton(AF_INET, argv[1], &sa.sin_addr) != 1) { perror("inet_pton"); return 1; }

    if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("connect"); return 1; }

    char line[BUFSZ];
    while (fgets(line, sizeof(line), stdin)) write(fd, line, strlen(line));

    close(fd);
    return 0;
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.