tcp_echo.c in C
A single-threaded echo server: bind, listen, accept, echo, repeat.
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 9099
#define BACKLOG 4
static int serve_client(int client) {
char buffer[512];
ssize_t n;
while ((n = read(client, buffer, sizeof buffer)) > 0) {
ssize_t written = 0;
while (written < n) {
ssize_t w = write(client, buffer + written, (size_t) (n - written));
if (w <= 0) {
return 0;
}
written += w;
}
}
return n == 0;
}
int main(void) {
int listener = socket(AF_INET, SOCK_STREAM, 0);
if (listener < 0) {
perror("socket");
return 1;
}
int reuse = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse);
struct sockaddr_in addr;
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(PORT);
if (bind(listener, (struct sockaddr *) &addr, sizeof addr) != 0) {
perror("bind");
close(listener);
return 1;
}
if (listen(listener, BACKLOG) != 0) {
perror("listen");
close(listener);
return 1;
}
printf("echoing on 127.0.0.1:%d\n", PORT);
for (int served = 0; served < 3; served++) {
struct sockaddr_in peer;
socklen_t peer_len = sizeof peer;
int client = accept(listener, (struct sockaddr *) &peer, &peer_len);
if (client < 0) {
perror("accept");
continue;
}
char who[INET_ADDRSTRLEN] = "?";
inet_ntop(AF_INET, &peer.sin_addr, who, sizeof who);
printf("client from %s\n", who);
if (!serve_client(client)) {
fprintf(stderr, "client dropped\n");
}
close(client);
}
close(listener);
return 0;
}
How it works
SO_REUSEADDRlets the port be rebound immediately after a restart.- The accept loop handles one client at a time to completion.
- Every error path closes what it opened and reports why.
Keywords and builtins used here
charcontinueforifintmainreturnserve_clientsize_tsizeofsockaddrsockaddr_insocklen_tssize_tstaticstructvoidwhile
The run, in numbers
- Lines
- 77
- Characters to type
- 1502
- Tokens
- 420
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 229 seconds.
Step 1 of 1 in Encore, step 14 of 14 in Systems programming.