All Courses
Expert Topics

Networking in C++


Network Programming Fundamentals

The OSI and TCP/IP Models

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      NETWORK LAYERS OVERVIEW                                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                               β”‚
β”‚   OSI Model              TCP/IP Model         What C++ Sockets Use           β”‚
β”‚   ─────────              ────────────         ────────────────────           β”‚
β”‚                                                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                      β”‚
β”‚  β”‚ Application β”‚        β”‚             β”‚       ◄── Your C++ Application       β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”‚ Application β”‚           HTTP, FTP, Custom Protocol β”‚
β”‚  β”‚ Presentationβ”‚        β”‚             β”‚                                      β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚
β”‚  β”‚   Session   β”‚                                                             β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       ◄── Socket API (TCP/UDP)       β”‚
β”‚  β”‚  Transport  β”‚        β”‚  Transport  β”‚           SOCK_STREAM, SOCK_DGRAM    β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚
β”‚  β”‚   Network   β”‚        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       ◄── IP Addresses               β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”‚   Network   β”‚           AF_INET, AF_INET6          β”‚
β”‚  β”‚  Data Link  β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       ◄── Handled by OS              β”‚
β”‚  β”‚  Physical   β”‚        β”‚Network Ifaceβ”‚                                      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚
β”‚                                                                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

TCP vs UDP Comparison

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         TCP vs UDP COMPARISON                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                              β”‚
β”‚  TCP (Transmission Control Protocol)     UDP (User Datagram Protocol)       β”‚
β”‚  ────────────────────────────────────    ────────────────────────────       β”‚
β”‚                                                                              β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     Connection?     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β”‚   β”‚  Client   │◄────────────────────│  Server   β”‚                           β”‚
β”‚   β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜    Established!     β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜                           β”‚
β”‚         β”‚                                 β”‚                                  β”‚
β”‚         │──── Data packet 1 ─────────────►│                                  β”‚
β”‚         │◄─── ACK ────────────────────────│                                  β”‚
β”‚         │──── Data packet 2 ─────────────►│                                  β”‚
β”‚         │◄─── ACK ────────────────────────│                                  β”‚
β”‚                                                                              β”‚
β”‚   βœ… Reliable (guaranteed delivery)    ❌ No guarantee                      β”‚
β”‚   βœ… Ordered (packets arrive in order) ❌ May arrive out of order           β”‚
β”‚   βœ… Error checked                     βœ… Error checked                     β”‚
β”‚   ❌ Slower (overhead)                 βœ… Faster (minimal overhead)         β”‚
β”‚   ❌ Connection required               βœ… Connectionless                    β”‚
β”‚                                                                              β”‚
β”‚   Use for:                             Use for:                              β”‚
β”‚   β€’ Web (HTTP/HTTPS)                   β€’ Video streaming                     β”‚
β”‚   β€’ Email (SMTP)                       β€’ Online gaming                       β”‚
β”‚   β€’ File transfer (FTP)                β€’ DNS queries                         β”‚
β”‚   β€’ Database connections               β€’ VoIP                                β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Client-Server Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     CLIENT-SERVER COMMUNICATION FLOW                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                              β”‚
β”‚        CLIENT                                        SERVER                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚   β”‚                 β”‚                          β”‚                 β”‚          β”‚
β”‚   β”‚  1. socket()    β”‚                          β”‚  1. socket()    β”‚          β”‚
β”‚   β”‚     Create      β”‚                          β”‚     Create      β”‚          β”‚
β”‚   β”‚                 β”‚                          β”‚                 β”‚          β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚  2. bind()      β”‚          β”‚
β”‚            β”‚                                   β”‚     Assign port β”‚          β”‚
β”‚            β”‚                                   β”‚                 β”‚          β”‚
β”‚            β”‚                                   β”‚  3. listen()    β”‚          β”‚
β”‚            β”‚                                   β”‚     Wait for    β”‚          β”‚
β”‚            β”‚                                   β”‚     connections β”‚          β”‚
β”‚            β”‚                                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚            β”‚                                            β”‚                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚   β”‚  2. connect()   β”‚ ─── TCP Handshake ────►  β”‚  4. accept()    β”‚          β”‚
β”‚   β”‚     Connect to  β”‚ ◄──────────────────────  β”‚     Accept      β”‚          β”‚
β”‚   β”‚     server      β”‚                          β”‚     connection  β”‚          β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚            β”‚                                            β”‚                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚   β”‚  3. send()      β”‚ ──── Request ─────────►  β”‚  5. recv()      β”‚          β”‚
β”‚   β”‚     Send data   β”‚                          β”‚     Receive     β”‚          β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚            β”‚                                            β”‚                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚   β”‚  4. recv()      β”‚ ◄─── Response ──────────  β”‚  6. send()      β”‚          β”‚
β”‚   β”‚     Receive     β”‚                          β”‚     Send reply  β”‚          β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚            β”‚                                            β”‚                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚   β”‚  5. close()     β”‚ ◄── Connection Close ──► β”‚  7. close()     β”‚          β”‚
β”‚   β”‚     Close       β”‚                          β”‚     Close       β”‚          β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Socket Basics

A socket is an endpoint for communication - like a phone number for your program.

Required Headers (Linux/Unix)

#include <sys/socket.h>   // socket(), bind(), listen(), accept(), connect()
#include <netinet/in.h>   // sockaddr_in, INADDR_ANY
#include <arpa/inet.h>    // inet_pton(), inet_ntop(), htons()
#include <unistd.h>       // close()
#include <netdb.h>        // getaddrinfo(), gethostbyname()
#include <cstring>        // memset()

Socket Types

// AF = Address Family, SOCK = Socket type

// TCP Socket (Stream) - Reliable, ordered, connection-based
int tcpSocket = socket(AF_INET, SOCK_STREAM, 0);

// UDP Socket (Datagram) - Fast, connectionless, no guarantees
int udpSocket = socket(AF_INET, SOCK_DGRAM, 0);

// IPv6 variants
int ipv6TcpSocket = socket(AF_INET6, SOCK_STREAM, 0);
int ipv6UdpSocket = socket(AF_INET6, SOCK_DGRAM, 0);

Socket Creation Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        SOCKET CREATION PARAMETERS                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                              β”‚
β”‚  socket(domain, type, protocol)                                              β”‚
β”‚          β”‚       β”‚      β”‚                                                    β”‚
β”‚          β”‚       β”‚      └── Usually 0 (auto-select based on type)           β”‚
β”‚          β”‚       β”‚                                                           β”‚
β”‚          β”‚       └── SOCK_STREAM ─── TCP (reliable, ordered)                β”‚
β”‚          β”‚           SOCK_DGRAM ──── UDP (fast, no guarantees)              β”‚
β”‚          β”‚           SOCK_RAW ────── Raw IP (advanced)                      β”‚
β”‚          β”‚                                                                   β”‚
β”‚          └── AF_INET ─────── IPv4 (192.168.1.1)                             β”‚
β”‚              AF_INET6 ────── IPv6 (2001:db8::1)                             β”‚
β”‚              AF_UNIX ─────── Local (file-based IPC)                         β”‚
β”‚                                                                              β”‚
β”‚  Returns: Socket file descriptor (int) or -1 on error                       β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Address Structure

// IPv4 Address Structure
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));          // Zero out the structure
addr.sin_family = AF_INET;               // IPv4
addr.sin_port = htons(8080);             // Port (host to network byte order)
addr.sin_addr.s_addr = INADDR_ANY;       // Accept on any interface

// For specific IP address
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);

// IPv6 Address Structure
sockaddr_in6 addr6;
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(8080);
addr6.sin6_addr = in6addr_any;

Byte Order Functions

// Network byte order = Big Endian (most significant byte first)
// Host byte order = May be Big or Little Endian

htons(port);    // Host TO Network Short (16-bit, for ports)
htonl(addr);    // Host TO Network Long  (32-bit, for addresses)
ntohs(port);    // Network TO Host Short
ntohl(addr);    // Network TO Host Long
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           BYTE ORDER MATTERS!                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                              β”‚
β”‚  Port 8080 (0x1F90) in different byte orders:                               β”‚
β”‚                                                                              β”‚
β”‚  Little Endian (x86):     Big Endian (Network):                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”                                     β”‚
β”‚  β”‚ 90  β”‚ 1F  β”‚     ──►    β”‚ 1F  β”‚ 90  β”‚                                     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜   htons()  β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜                                     β”‚
β”‚                                                                              β”‚
β”‚  ALWAYS use htons() for ports and htonl() for addresses!                    β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

TCP Client

Connect to Server

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>

int connectToServer(const char* host, int port) {
    // Create socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) return -1;

    // Server address
    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    inet_pton(AF_INET, host, &serverAddr.sin_addr);

    // Connect
    if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        close(sock);
        return -1;
    }

    return sock;
}

void sendMessage(int sock, const string& msg) {
    send(sock, msg.c_str(), msg.length(), 0);
}

string receiveMessage(int sock) {
    char buffer[1024];
    ssize_t bytes = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (bytes > 0) {
        buffer[bytes] = '\0';
        return string(buffer);
    }
    return "";
}

TCP Server

Basic Server

int createServer(int port) {
    // Create socket
    int serverSock = socket(AF_INET, SOCK_STREAM, 0);

    // Allow reuse
    int opt = 1;
    setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // Bind
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);
    bind(serverSock, (sockaddr*)&addr, sizeof(addr));

    // Listen
    listen(serverSock, 10);  // Backlog of 10

    return serverSock;
}

void acceptClients(int serverSock) {
    while (true) {
        sockaddr_in clientAddr;
        socklen_t clientLen = sizeof(clientAddr);

        // Accept (blocks)
        int clientSock = accept(serverSock,
                               (sockaddr*)&clientAddr,
                               &clientLen);

        if (clientSock >= 0) {
            // Handle client
            handleClient(clientSock);
            close(clientSock);
        }
    }
}

Multi-Threaded Server

void handleClient(int clientSock) {
    char buffer[1024];
    while (true) {
        ssize_t bytes = recv(clientSock, buffer, sizeof(buffer), 0);
        if (bytes <= 0) break;

        // Echo back
        send(clientSock, buffer, bytes, 0);
    }
}

void acceptClientsThreaded(int serverSock) {
    while (true) {
        sockaddr_in clientAddr;
        socklen_t clientLen = sizeof(clientAddr);
        int clientSock = accept(serverSock,
                               (sockaddr*)&clientAddr, &clientLen);

        if (clientSock >= 0) {
            thread t(handleClient, clientSock);
            t.detach();  // Run independently
        }
    }
}

UDP Communication

UDP Server

int createUDPServer(int port) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);

    bind(sock, (sockaddr*)&addr, sizeof(addr));
    return sock;
}

void receiveUDP(int sock) {
    char buffer[1024];
    sockaddr_in clientAddr;
    socklen_t clientLen = sizeof(clientAddr);

    ssize_t bytes = recvfrom(sock, buffer, sizeof(buffer), 0,
                             (sockaddr*)&clientAddr, &clientLen);

    if (bytes > 0) {
        buffer[bytes] = '\0';
        cout << "Received: " << buffer << endl;

        // Reply
        sendto(sock, "ACK", 3, 0,
               (sockaddr*)&clientAddr, clientLen);
    }
}

UDP Client

void sendUDP(const char* host, int port, const string& msg) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    inet_pton(AF_INET, host, &serverAddr.sin_addr);

    sendto(sock, msg.c_str(), msg.length(), 0,
           (sockaddr*)&serverAddr, sizeof(serverAddr));

    close(sock);
}

Non-Blocking I/O

select()

#include <sys/select.h>

void selectLoop(int serverSock, vector<int>& clients) {
    fd_set readSet;

    while (true) {
        FD_ZERO(&readSet);
        FD_SET(serverSock, &readSet);

        int maxFd = serverSock;
        for (int fd : clients) {
            FD_SET(fd, &readSet);
            maxFd = max(maxFd, fd);
        }

        timeval timeout = {1, 0};  // 1 second
        int ready = select(maxFd + 1, &readSet, nullptr, nullptr, &timeout);

        if (ready > 0) {
            // Check server socket
            if (FD_ISSET(serverSock, &readSet)) {
                int newClient = accept(serverSock, nullptr, nullptr);
                clients.push_back(newClient);
            }

            // Check client sockets
            for (int fd : clients) {
                if (FD_ISSET(fd, &readSet)) {
                    // Read from client
                }
            }
        }
    }
}

poll()

#include <poll.h>

void pollLoop(int serverSock) {
    vector<pollfd> fds;
    fds.push_back({serverSock, POLLIN, 0});

    while (true) {
        int ready = poll(fds.data(), fds.size(), 1000);  // 1s timeout

        if (ready > 0) {
            for (auto& pfd : fds) {
                if (pfd.revents & POLLIN) {
                    if (pfd.fd == serverSock) {
                        // Accept new connection
                    } else {
                        // Read from client
                    }
                }
            }
        }
    }
}

Recommended Conventions

βœ… Do

// 1. Check return values
if (connect(sock, addr, len) < 0) {
    perror("connect failed");
}

// 2. Set SO_REUSEADDR
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

// 3. Close sockets properly
close(sock);

// 4. Handle partial reads/writes
ssize_t sendAll(int sock, const char* data, size_t len) {
    size_t sent = 0;
    while (sent < len) {
        ssize_t n = send(sock, data + sent, len - sent, 0);
        if (n <= 0) return -1;
        sent += n;
    }
    return sent;
}

❌ Don't

// 1. Don't ignore byte order
addr.sin_port = 8080;  // WRONG
addr.sin_port = htons(8080);  // Correct

// 2. Don't assume recv fills buffer
char buffer[1024];
recv(sock, buffer, 1024, 0);
buffer[1023] = '\0';  // May not be null-terminated!

// 3. Don't forget to close
// Memory/resource leak if socket not closed

Cheat Sheet

// Create socket
socket(AF_INET, SOCK_STREAM, 0);  // TCP
socket(AF_INET, SOCK_DGRAM, 0);   // UDP

// Address setup
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, "ip", &addr.sin_addr);

// TCP Server
bind(sock, addr, sizeof(addr));
listen(sock, backlog);
accept(sock, clientAddr, &len);

// TCP Client
connect(sock, addr, sizeof(addr));

// Send/Receive
send(sock, data, len, 0);
recv(sock, buffer, buflen, 0);

// UDP
sendto(sock, data, len, 0, addr, addrlen);
recvfrom(sock, buf, len, 0, addr, &addrlen);

// Cleanup
close(sock);

Compile & Run

g++ -std=c++17 -Wall examples.cpp -o examples && ./examples