{"id":2721,"date":"2025-07-07T18:59:00","date_gmt":"2025-07-07T23:59:00","guid":{"rendered":"http:\/\/www.paleotechnologist.net\/?p=2721"},"modified":"2025-07-07T18:59:00","modified_gmt":"2025-07-07T23:59:00","slug":"socket-to-em","status":"publish","type":"post","link":"https:\/\/www.paleotechnologist.net\/?p=2721","title":{"rendered":"Socket to &#8217;em"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The really cool, game-changing thing about the Internet is that it allows us to leverage the true N^2 value of large networks. Specifically, whenever a computer has a persistent Internet connection, it can exchange information with any other Internet-connected device at any time, quickly and easily.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When writing Internet-aware applications, such communications are often done with TCP or UDP sockets. These virtual connections represent a specific connection from one computer to another, through which data can be transferred.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What is needed for TCP\/IP (UDP is similar but without verification steps) is a server program (to listen for incoming connections) and a client program (to contact a server with a request). As an easily-modified example, here is a server program in C that accepts a single byte, increments it (allowing rollover), and sends it back.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* server.c : minimal TCP server that receives one uint8,\n              applies myFunction() (here: ++ with wrap-around),\n              and sends it back.                                *\/\n\n#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;stdint.h>\n#include &lt;unistd.h>\n#include &lt;string.h>\n#include &lt;arpa\/inet.h>\n#include &lt;sys\/socket.h>\n#include &lt;netinet\/in.h>\n\n#define PORT 10000          \/* listen port; change if you like *\/\n\n\/* Your pluggable transform ---------------------------------- *\/\nstatic uint8_t myFunction(uint8_t x) {\n    return x + 1;           \/* uint8_t overflow wraps naturally *\/\n}\n\/* ----------------------------------------------------------- *\/\n\nint main(void){\n\n    int srv_fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (srv_fd &lt; 0) { perror(\"socket\"); exit(EXIT_FAILURE); }\n\n    \/* allow quick restart (otherwise TIME_WAIT delays) *\/\n    int opt = 1;\n    setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof opt);\n\n    struct sockaddr_in addr = {0};\n    addr.sin_family      = AF_INET;\n    addr.sin_addr.s_addr = htonl(INADDR_ANY); \/* 0.0.0.0 *\/\n    addr.sin_port        = htons(PORT);\n\n    if (bind(srv_fd, (struct sockaddr *)&amp;addr, sizeof addr) &lt; 0) {\n        perror(\"bind\"); exit(EXIT_FAILURE);\n    }\n    if (listen(srv_fd, 1) &lt; 0) { perror(\"listen\"); exit(EXIT_FAILURE); }\n\n    printf(\"Server listening on port %d \u2026\\n\", PORT);\n\n    for (;;) {\n        struct sockaddr_in cli_addr;\n        socklen_t cli_len = sizeof cli_addr;\n        int cfd = accept(srv_fd, (struct sockaddr *)&amp;cli_addr, &amp;cli_len);\n        if (cfd &lt; 0) { perror(\"accept\"); continue; }\n\n        uint8_t in_byte;\n        ssize_t n = recv(cfd, &amp;in_byte, 1, 0);\n        if (n == 1) {\n            uint8_t out_byte = myFunction(in_byte);\n            send(cfd, &amp;out_byte, 1, 0);\n            printf(\" %u -> %u from %s\\n\",\n                   in_byte, out_byte, inet_ntoa(cli_addr.sin_addr));\n        }\n        close(cfd);\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a client program, which calls the server, sends a byte, and reports what it gets back. <br>(Change the IP address if the programs are not running on the same machine.)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* client.c : minimal TCP client that sends a uint8\n              and prints the transformed result.               *\/\n\n#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;stdint.h>\n#include &lt;unistd.h>\n#include &lt;arpa\/inet.h>\n#include &lt;sys\/socket.h>\n#include &lt;netinet\/in.h>\n\n#define PORT 10000          \/* must match server *\/\n#define SERVER_IP \"127.0.0.1\" \/* change to LAN IP if needed *\/\n\nint main(int argc, char **argv){\n\n    uint8_t value = 42;                          \/* default test value *\/\n    if (argc == 2) value = (uint8_t)atoi(argv&#91;1]);\n\n    int fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (fd &lt; 0) { perror(\"socket\"); exit(EXIT_FAILURE); }\n\n    struct sockaddr_in srv = {0};\n    srv.sin_family = AF_INET;\n    srv.sin_port   = htons(PORT);\n    if (inet_pton(AF_INET, SERVER_IP, &amp;srv.sin_addr) != 1) {\n        fprintf(stderr, \"Bad server IP\\n\"); exit(EXIT_FAILURE);\n    }\n\n    if (connect(fd, (struct sockaddr *)&amp;srv, sizeof srv) &lt; 0) {\n        perror(\"connect\"); exit(EXIT_FAILURE);\n    }\n\n    if (send(fd, &amp;value, 1, 0) != 1) { perror(\"send\"); exit(EXIT_FAILURE); }\n\n    uint8_t reply;\n    if (recv(fd, &amp;reply, 1, 0) != 1) { perror(\"recv\"); exit(EXIT_FAILURE); }\n\n    printf(\"Sent %u, got %u\\n\", value, reply);\n\n    close(fd);\n    return 0;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(Code provided by GPT-o3.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TCP and UDP sockets can enable Internet-aware programs to communicate directly with each other&#8230; <a href=\"https:\/\/www.paleotechnologist.net\/?p=2721\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"footnotes":""},"categories":[249,216,210,217,226,223,277,490,214],"tags":[],"class_list":["post-2721","post","type-post","status-publish","format-standard","hentry","category-c","category-coding","category-digital","category-digitalcitizenship","category-how-to","category-internet","category-linux","category-networking","category-sysadmin"],"_links":{"self":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts\/2721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2721"}],"version-history":[{"count":4,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts\/2721\/revisions"}],"predecessor-version":[{"id":5322,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts\/2721\/revisions\/5322"}],"wp:attachment":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}