LinuxNetworkProgramming
A comprehensive guide for Linux Network (Socket) programming
Install / Use
/learn @nguyenchiemminhvu/LinuxNetworkProgrammingREADME
- Introduction
- Sockets
- Programming Client-Server Models
- Networking Libraries
- Conclusion
Introduction
In my opinion, Linux network programming, especially socket programming, isn’t that difficult. However, learning this topic on your own can be challenging because many online resources are unclear, and sample codes often only cover the basics. You might find yourself unsure of what to do next. That's why I created this tutorial. It aims to give you clear guidelines and plenty of examples to help you understand better.
Linux network programming deals with the interaction between processes using network interfaces. It enables interprocess communication (IPC), allowing data exchange between processes running on the same machine or on different machines connected over a network.
The foundation of Linux network programming lies in the use of sockets, a universal API designed for interprocess communication. Sockets originated from BSD Unix in 1983 and were later standardized by POSIX, making them a cornerstone of modern networking.
Sockets
A socket is an endpoint for communication. Think of it as a door through which data flows in and out of a process. Processes use sockets to send and receive messages, enabling seamless IPC.
Sockets were initially designed to support two domains:
Unix Domain (Unix): Used for communication between processes within the same operating system.
Internet Domain (INET): Used for communication between processes on different systems connected via a TCP/IP network.
Unix domain sockets are used for IPC within the same operating system. They are faster than INET sockets because they don't require network protocol overhead. Instead of IP addresses, Unix domain sockets use file system paths for addressing.
INET domain sockets are used for communication between processes on different systems connected over a network. These sockets rely on the TCP/IP protocol stack, which ensures data integrity and delivery.
Two common protocols used with INET domain sockets are:
TCP (Transmission Control Protocol): Provides reliable, ordered, and error-checked delivery of data.
UDP (User Datagram Protocol): Provides fast, connectionless data transmission without guarantees of delivery.
Type of sockets
The BSD socket API supports several types of sockets, which determine how data is transmitted between processes:
Stream Sockets (SOCK_STREAM): These provide a reliable, connection-oriented communication protocol. Data is sent and received as a continuous stream of bytes. Typically used with TCP (Transmission Control Protocol).
Datagram Sockets (SOCK_DGRAM): These provide a connectionless communication protocol. Data is sent in discrete packets, and delivery isn't guaranteed. Typically used with UDP (User Datagram Protocol).
Raw Sockets (SOCK_RAW): These allow processes to access lower-level network protocols directly, bypassing the standard TCP or UDP layers. Useful for custom protocol implementations or network monitoring tools.
Addressing sockets
In the INET domain, sockets are identified by two components:
IP Address: A 32-bit number (IPv4) or a 128-bit number (IPv6) that uniquely identifies a device on a network. IPv4 addresses are often represented in dotted decimal notation, such as 192.168.1.1.
Port Number: A 16-bit number that identifies a specific service or application on the device. For example, web servers typically use port 80 (HTTP) or 443 (HTTPS).
Check some of well-known services in Linux system via /etc/services file. Ports under 1024 are often considered special, and usually require special OS privileges to use.
worker@7e4a84e41875:~/study_workspace/LinuxNetworkProgramming$ cat /etc/services
tcpmux 1/tcp # TCP port service multiplexer
echo 7/tcp
echo 7/udp
...
ftp 21/tcp
fsp 21/udp fspd
ssh 22/tcp # SSH Remote Login Protocol
telnet 23/tcp
smtp 25/tcp mail
...
http 80/tcp www # WorldWideWeb HTTP
...
Socket APIs
getprotobyname()
#include <netdb.h>
struct protoent *getprotobyname(const char *name);
Sample usage:
struct protoent *proto;
proto = getprotobyname("tcp");
if (proto)
{
printf("Protocol number for TCP: %d\n", proto->p_proto);
}
Description: getprotobyname() returns a protoent structure for the given protocol name, which contains information about the protocol.
getservbyname()
#include <netdb.h>
struct servent *getservbyname(const char *name, const char *proto);
Sample usage:
struct servent *serv;
serv = getservbyname("http", "tcp");
if (serv)
{
printf("Port number for HTTP: %d\n", ntohs(serv->s_port));
}
Description: getservbyname() returns a servent structure for the given service name and protocol, which contains information about the service.
getaddrinfo()
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
struct addrinfo {
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
int ai_protocol; // use 0 for "any"
size_t ai_addrlen; // size of ai_addr in bytes
struct sockaddr *ai_addr; // struct sockaddr_in or _in6
char *ai_canonname; // full canonical hostname
struct addrinfo *ai_next; // linked list, next node
};
int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
const char *service, // e.g. "http" or port number
const struct addrinfo *hints,
struct addrinfo **res);
Struct addrinfo has the pointer to struct sockaddr which is used in many socket functions.
Sample usage:
int status;
struct addrinfo hints;
struct addrinfo *servinfo; // will point to the results
memset(&hints, 0, sizeof(hints)); // make sure the struct is empty
hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
// servinfo now points to a linked list of 1 or more struct addrinfos
// ... do everything until you don't need servinfo anymore ....
freeaddrinfo(servinfo); // free the linked-list
Description: getaddrinfo() is used to get a list of address structures for the specified node and service, which can be used to create and connect sockets.
htonl(), htons(), ntohl(), ntohs()
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t
Related Skills
node-connect
340.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
340.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.2kCommit, push, and open a PR
