Backend Development 35 min read

Understanding Linux Kernel Sockets: Concepts, Types, and API Functions

This article provides a comprehensive overview of Linux socket programming, covering socket definitions, classifications such as stream, datagram, and raw sockets, connection-oriented versus connectionless communication, IP/port/MAC addressing, byte order considerations, and practical C API examples for creating and using sockets.

Deepin Linux
Deepin Linux
Deepin Linux
Understanding Linux Kernel Sockets: Concepts, Types, and API Functions

Socket Overview

Socket, introduced by BSD in 1982, is an abstract I/O interface that represents a communication endpoint composed of an IP address, protocol (TCP/UDP) and port number. It allows processes to read, write and close network connections just like files.

Socket Types

Internet sockets are classified by transmission mode into stream sockets ( SOCK_STREAM ) that provide reliable, ordered byte‑stream communication using TCP, datagram sockets ( SOCK_DGRAM ) that provide connection‑less, unordered, best‑effort delivery using UDP, and raw sockets ( SOCK_RAW ) that give direct access to lower‑level protocols for analysis.

Connection‑oriented vs Connection‑less

Stream sockets establish a virtual circuit before data transfer; the kernel guarantees delivery, ordering and retransmission, which is why protocols such as HTTP and FTP use them. Datagram sockets send independent packets that may follow different routes, may be lost or arrive out of order, but have lower latency, suitable for DNS, video chat, etc.

IP, Port and MAC

IP addresses identify hosts (IPv4 or IPv6), ports identify individual processes on a host, and MAC addresses uniquely identify network interface cards on the local LAN. Together they enable the kernel to deliver incoming packets to the correct socket.

Byte Order

Network protocols use big‑endian (network byte order). Functions htons , htonl , ntohs , ntohl convert between host and network byte order, ensuring portable communication between little‑endian (e.g., x86) and big‑endian machines.

Socket API Functions

Typical workflow: create a socket with socket() , bind it to an address with bind() , listen (for TCP) with listen() , accept connections with accept() , and exchange data using send() / recv() or sendto() / recvfrom() . Example server and client code are shown below.

#include
#include
#include
#include
#include
#include
int main(int arc, char **argv)
{
    int server_sockfd = -1;
    socklen_t server_len = 0;
    socklen_t client_len = 0;
    char buffer[512];
    ssize_t result = 0;

    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;

    // create datagram socket
    server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    // set listening port and IP
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(9739);
    server_len = sizeof(server_addr);

    // bind socket
    bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);

    // ignore child termination
    signal(SIGCHLD, SIG_IGN);

    while (1)
    {
        // receive data
        result = recvfrom(server_sockfd, buffer, sizeof(buffer), 0,
                          (struct sockaddr *)&client_addr, &client_len);
        if (fork() == 0)
        {
            // process data
            buffer[0] += 'a' - 'A';
            // send processed data
            sendto(server_sockfd, buffer, sizeof(buffer), 0,
                   (struct sockaddr *)&client_addr, client_len);
            printf("%c\n", buffer[0]);
            exit(0);
        }
    }

    close(server_sockfd);
}
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
    struct sockaddr_in server_addr;
    socklen_t server_len = 0;
    int sockfd = -1;
    char c = 'A';

    if (argc > 1)
    {
        c = argv[1][0];
    }

    // create datagram socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    // set server IP and port
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(9739);
    server_len = sizeof(server_addr);

    // send data to server
    sendto(sockfd, &c, sizeof(char), 0,
           (struct sockaddr *)&server_addr, server_len);

    // receive processed data
    recvfrom(sockfd, &c, sizeof(char), 0, 0, 0);

    printf("char from server = %c\n", c);
    close(sockfd);
    exit(0);
}
C++tcpLinuxNetwork ProgrammingsocketUDP
Deepin Linux
Written by

Deepin Linux

Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.