Networking#
In C, networking is the BSD sockets API plus a handful of well-known libraries layered on top.
Sockets#
The system call interface is the foundation. A minimal TCP client.
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
int main(void) {
struct addrinfo hints = {0}, *res;
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo("example.com", "80", &hints, &res) != 0) return 1;
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) return 1;
const char *req = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
send(fd, req, strlen(req), 0);
char buf[4096];
ssize_t n;
while ((n = recv(fd, buf, sizeof buf, 0)) > 0) {
fwrite(buf, 1, (size_t)n, stdout);
}
close(fd);
freeaddrinfo(res);
}
A minimal TCP server uses socket → bind → listen → accept.
Address Resolution#
Always use getaddrinfo / getnameinfo; the older gethostbyname is
deprecated and IPv4-only.
I/O Multiplexing#
For more than a handful of connections, don’t thread per connection; use the kernel’s event interface.
select/poll, portable but O(n) per call.epoll(Linux),kqueue(BSD/macOS),IOCP(Windows), scalable.io_uring(Linux), async system calls; the modern high-perf path.
TLS#
Don’t roll your own. The standard libraries.
OpenSSL , everywhere; large API surface.
BoringSSL, Google’s fork; used in Chrome / Android.
mbedTLS, embedded-friendly.
wolfSSL , compact alternative.
LibreSSL , OpenBSD’s OpenSSL fork.
The structure of an OpenSSL client.
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_default_verify_paths(ctx);
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, fd);
SSL_set_tlsext_host_name(ssl, "example.com");
SSL_connect(ssl);
SSL_write(ssl, req, strlen(req));
SSL_read(ssl, buf, sizeof buf);
Always verify certificates: SSL_get_verify_result and matching the
hostname.
HTTP Clients#
HTTP Servers (Embeddable)#
libmicrohttpd , small.
civetweb , single-file.
mongoose , popular in embedded.
Async / Event Loops#
Higher-Level Protocols#
c-ares , async DNS.
paho.mqtt.c , MQTT.
MariaDB Connector/C, libpq, database drivers.
Pitfalls#
Partial reads / writes, always loop until the byte count you wanted, or use
send/recvflags.Endianness, use
htons/htonlandntohs/ntohlfor all multi-byte values on the wire.Buffer sizes, never trust user-supplied lengths; validate.
TLS verification, the default is often “accept anything” until you wire up a CA bundle. Always verify.
Blocking writes can deadlock, non-blocking sockets + event loop, or per-call timeouts, for anything serious.