Skip to content

Instantly share code, notes, and snippets.

@vastus
Created January 21, 2025 02:35
Show Gist options
  • Save vastus/78d2eb14c6ba2284496337d162075ebd to your computer and use it in GitHub Desktop.
Save vastus/78d2eb14c6ba2284496337d162075ebd to your computer and use it in GitHub Desktop.
TCP echo server w/ fork handler
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define PORT 42069
int handle_new_conn(int conn);
int handle_conn(int conn);
int main(void)
{
// server, client addrs
socklen_t client_socklen;
struct sockaddr_in server_addr, client_addr;
memset(&server_addr, 0, sizeof server_addr);
memset(&client_addr, 0, sizeof client_addr);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
// socket
int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if (sock < 0) {
perror("socket failed");
exit(1);
}
// bind
if (bind(sock, (const struct sockaddr *)&server_addr, sizeof server_addr) < 0) {
perror("failed to bind");
exit(1);
}
// listen
if (listen(sock, 8) < 0) {
perror("listen failed");
exit(1);
}
int nclients = 0;
for (;;) {
int conn = accept(sock, (struct sockaddr *)&client_addr, &client_socklen);
if (conn < 0) {
perror("failed to accept");
usleep(200000);
continue;
}
handle_new_conn(conn);
}
return 0;
}
int handle_new_conn(int conn)
{
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
close(conn);
return pid;
}
if (pid != 0) {
return 0;
}
handle_conn(conn);
if (close(conn) < 0) {
perror("failed to close client connection");
return -1;
}
return 0;
}
int handle_conn(int conn)
{
int nread;
int nwritten;
char buf[BUFSIZ];
while (nread = read(conn, buf, BUFSIZ), nread > 0) {
nwritten = write(conn, buf, nread);
if (nwritten < 0) {
perror("failed to write to client");
}
}
if (nread < 0) {
perror("failed to read from client");
}
return nread;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment