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.
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.
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.
/* server.c : minimal TCP server that receives one uint8,
applies myFunction() (here: ++ with wrap-around),
and sends it back. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 10000 /* listen port; change if you like */
/* Your pluggable transform ---------------------------------- */
static uint8_t myFunction(uint8_t x) {
return x + 1; /* uint8_t overflow wraps naturally */
}
/* ----------------------------------------------------------- */
int main(void){
int srv_fd = socket(AF_INET, SOCK_STREAM, 0);
if (srv_fd < 0) { perror("socket"); exit(EXIT_FAILURE); }
/* allow quick restart (otherwise TIME_WAIT delays) */
int opt = 1;
setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt);
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 0.0.0.0 */
addr.sin_port = htons(PORT);
if (bind(srv_fd, (struct sockaddr *)&addr, sizeof addr) < 0) {
perror("bind"); exit(EXIT_FAILURE);
}
if (listen(srv_fd, 1) < 0) { perror("listen"); exit(EXIT_FAILURE); }
printf("Server listening on port %d …\n", PORT);
for (;;) {
struct sockaddr_in cli_addr;
socklen_t cli_len = sizeof cli_addr;
int cfd = accept(srv_fd, (struct sockaddr *)&cli_addr, &cli_len);
if (cfd < 0) { perror("accept"); continue; }
uint8_t in_byte;
ssize_t n = recv(cfd, &in_byte, 1, 0);
if (n == 1) {
uint8_t out_byte = myFunction(in_byte);
send(cfd, &out_byte, 1, 0);
printf(" %u -> %u from %s\n",
in_byte, out_byte, inet_ntoa(cli_addr.sin_addr));
}
close(cfd);
}
}
Here is a client program, which calls the server, sends a byte, and reports what it gets back.
(Change the IP address if the programs are not running on the same machine.)
/* client.c : minimal TCP client that sends a uint8
and prints the transformed result. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 10000 /* must match server */
#define SERVER_IP "127.0.0.1" /* change to LAN IP if needed */
int main(int argc, char **argv){
uint8_t value = 42; /* default test value */
if (argc == 2) value = (uint8_t)atoi(argv[1]);
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) { perror("socket"); exit(EXIT_FAILURE); }
struct sockaddr_in srv = {0};
srv.sin_family = AF_INET;
srv.sin_port = htons(PORT);
if (inet_pton(AF_INET, SERVER_IP, &srv.sin_addr) != 1) {
fprintf(stderr, "Bad server IP\n"); exit(EXIT_FAILURE);
}
if (connect(fd, (struct sockaddr *)&srv, sizeof srv) < 0) {
perror("connect"); exit(EXIT_FAILURE);
}
if (send(fd, &value, 1, 0) != 1) { perror("send"); exit(EXIT_FAILURE); }
uint8_t reply;
if (recv(fd, &reply, 1, 0) != 1) { perror("recv"); exit(EXIT_FAILURE); }
printf("Sent %u, got %u\n", value, reply);
close(fd);
return 0;
}
(Code provided by GPT-o3.)
