Socket Programming Fundamentals
Overview
- What you’ll learn: The socket abstraction, the Berkeley socket API, TCP vs UDP sockets, client-server communication patterns, and hands-on examples with Python and netcat.
- Prerequisites: Lesson 12 – IP Addressing, Subnetting, and CIDR
- Estimated reading time: 22 minutes
Introduction
Every networked application — from web servers and database clients to chat programs and IoT sensors — relies on sockets to send and receive data across a network. A socket is an endpoint for communication, identified by an IP address and a port number. It is the fundamental abstraction that bridges the gap between application code and the underlying TCP/IP protocol stack.
The socket API was originally developed as part of BSD Unix in the early 1980s and has since become the standard network programming interface across all major operating systems. Understanding sockets is essential for anyone who wants to build, debug, or troubleshoot networked applications on Linux.
In this lesson, you will learn how sockets work at a conceptual level, explore the key system calls in the socket lifecycle, and write practical examples using both Python and command-line tools like netcat.
What is a Socket?
A socket is a software endpoint that establishes bidirectional communication between a server process and one or more client processes. Think of it as a telephone — one side dials (the client connects) and the other side picks up (the server accepts). Every socket is uniquely identified by the combination of a protocol (TCP or UDP), a local IP address, and a local port number.
On Linux, sockets are represented as file descriptors, which means you can use standard file operations like read() and write() to send and receive data. This is consistent with the Unix philosophy of “everything is a file.”
# View all open sockets on the system
$ ss -tunap
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6))
udp UNCONN 0 0 127.0.0.53:53 0.0.0.0:* users:(("systemd-resolve",pid=890,fd=13))
# Count open sockets by state
$ ss -s
Total: 187
TCP: 12 (estab 3, closed 2, orphaned 0, timewait 1)
Transport Total IP IPv6
RAW 1 0 1
UDP 4 3 1
TCP 10 7 3
INET 15 10 5
FRAG 0 0 0
The Socket Lifecycle
The socket API follows a well-defined sequence of system calls. For a TCP connection, the server and client follow different but complementary paths:
Server side: socket() → bind() → listen() → accept() → recv()/send() → close()
Client side: socket() → connect() → send()/recv() → close()
# TCP Server in Python
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 1. Create socket
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('0.0.0.0', 9000)) # 2. Bind to address and port
server.listen(5) # 3. Start listening (backlog=5)
print("Server listening on port 9000...")
conn, addr = server.accept() # 4. Accept incoming connection
print(f"Connection from {addr}")
data = conn.recv(1024) # 5. Receive data
print(f"Received: {data.decode()}")
conn.send(b"Hello from server!n") # 6. Send response
conn.close() # 7. Close connection
server.close()
# TCP Client in Python
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 1. Create socket
client.connect(('127.0.0.1', 9000)) # 2. Connect to server
client.send(b"Hello from client!n") # 3. Send data
response = client.recv(1024) # 4. Receive response
print(f"Server says: {response.decode()}")
client.close() # 5. Close connection
TCP vs UDP Sockets
TCP sockets (SOCK_STREAM) provide reliable, ordered, connection-oriented communication. UDP sockets (SOCK_DGRAM) provide fast, connectionless, best-effort delivery. The choice depends on your application requirements.
# UDP Server in Python
import socket
udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_server.bind(('0.0.0.0', 9001))
print("UDP server listening on port 9001...")
data, addr = udp_server.recvfrom(1024) # No accept() needed
print(f"Received from {addr}: {data.decode()}")
udp_server.sendto(b"UDP reply!n", addr)
udp_server.close()
# UDP Client in Python
import socket
udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_client.sendto(b"Hello UDP!n", ('127.0.0.1', 9001))
data, addr = udp_client.recvfrom(1024)
print(f"Reply: {data.decode()}")
udp_client.close()
Hands-On with Netcat
Netcat (nc) is the “Swiss army knife” of networking. It can create TCP and UDP connections from the command line, making it invaluable for testing and debugging socket-based services.
# Start a TCP listener on port 9000
$ nc -l -p 9000
# In another terminal, connect to it
$ nc 127.0.0.1 9000
Hello from netcat client! # Type and press Enter — appears on the listener
# UDP mode: use the -u flag
$ nc -u -l -p 9001 # UDP listener
$ nc -u 127.0.0.1 9001 # UDP client
# Send a file over TCP
$ nc -l -p 9000 > received_file.txt # Receiver
$ nc 127.0.0.1 9000 < /etc/hostname # Sender
# Port scanning with netcat
$ nc -zv 192.168.1.1 20-80
Connection to 192.168.1.1 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.1 80 port [tcp/http] succeeded!
Socket Options and Tuning
Socket options allow you to fine-tune socket behavior. Common options include SO_REUSEADDR (allow address reuse), SO_KEEPALIVE (detect dead connections), and TCP_NODELAY (disable Nagle’s algorithm for low-latency applications).
# View socket buffer sizes
$ sysctl net.core.rmem_default
net.core.rmem_default = 212992
$ sysctl net.core.wmem_default
net.core.wmem_default = 212992
# View TCP keepalive settings
$ sysctl net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 7200
$ sysctl net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalive_intvl = 75
$ sysctl net.ipv4.tcp_keepalive_probes
net.ipv4.tcp_keepalive_probes = 9
# Increase socket buffer size (temporary)
$ sudo sysctl -w net.core.rmem_max=16777216
$ sudo sysctl -w net.core.wmem_max=16777216
Key Takeaways
- A socket is a communication endpoint identified by a protocol, IP address, and port number — it is the fundamental building block of all networked applications.
- TCP sockets (
SOCK_STREAM) provide reliable, ordered delivery; UDP sockets (SOCK_DGRAM) provide fast, connectionless communication. - The server socket lifecycle follows:
socket()→bind()→listen()→accept()→recv()/send()→close(). - Netcat (
nc) is an essential command-line tool for testing TCP and UDP connections, transferring files, and port scanning. - Socket options like
SO_REUSEADDR,SO_KEEPALIVE, andTCP_NODELAYallow fine-tuning of socket behavior for specific application needs.
What’s Next
In Lesson 14, you will learn Routing and Switching Basics — how packets are forwarded between networks, how routing tables work, and how Linux can function as a router.
繁體中文
概述
- 學習目標:Socket 抽象概念、Berkeley socket API、TCP 與 UDP socket、用戶端-伺服器通訊模式,以及使用 Python 和 netcat 的實作範例。
- 先決條件:第 12 課 – IP 定址、子網劃分與 CIDR
- 預計閱讀時間:22 分鐘
簡介
每個網路應用程式——從網頁伺服器和資料庫用戶端到聊天程式和物聯網感測器——都依靠 socket 在網路上發送和接收資料。Socket 是通訊的端點,由 IP 位址和連接埠號碼標識。它是連接應用程式碼與底層 TCP/IP 協定堆疊的基本抽象。
Socket API 最初於 1980 年代初期作為 BSD Unix 的一部分開發,此後已成為所有主要作業系統的標準網路程式設計介面。了解 socket 對於想要在 Linux 上建構、除錯或排除網路應用程式問題的任何人來說都是必不可少的。
在本課程中,您將在概念層面了解 socket 的工作原理,探索 socket 生命週期中的關鍵系統呼叫,並使用 Python 和 netcat 等命令列工具撰寫實際範例。
什麼是 Socket?
Socket 是建立伺服器行程與一個或多個用戶端行程之間雙向通訊的軟體端點。可以把它想像成電話——一方撥號(用戶端連線),另一方接聽(伺服器接受)。每個 socket 由協定(TCP 或 UDP)、本地 IP 位址和本地連接埠號碼的組合唯一標識。
在 Linux 上,socket 表示為檔案描述符,這意味著您可以使用標準檔案操作(如 read() 和 write())來發送和接收資料。這與 Unix「一切皆檔案」的哲學一致。
Socket 生命週期
Socket API 遵循一個明確定義的系統呼叫序列。對於 TCP 連線,伺服器和用戶端遵循不同但互補的路徑:
伺服器端:socket() → bind() → listen() → accept() → recv()/send() → close()
用戶端:socket() → connect() → send()/recv() → close()
TCP 與 UDP Socket
TCP socket(SOCK_STREAM)提供可靠的、有序的、連線導向的通訊。UDP socket(SOCK_DGRAM)提供快速的、無連線的、盡力而為的交付。選擇取決於您的應用程式需求。
使用 Netcat 實作
Netcat(nc)是網路的「瑞士軍刀」。它可以從命令列建立 TCP 和 UDP 連線,對於測試和除錯基於 socket 的服務非常有價值。
Socket 選項與調校
Socket 選項允許您微調 socket 行為。常見選項包括 SO_REUSEADDR(允許位址重用)、SO_KEEPALIVE(偵測死連線)和 TCP_NODELAY(停用 Nagle 演算法以用於低延遲應用程式)。
重要觀念
- Socket 是由協定、IP 位址和連接埠號碼標識的通訊端點——它是所有網路應用程式的基本建構區塊。
- TCP socket(
SOCK_STREAM)提供可靠的、有序的交付;UDP socket(SOCK_DGRAM)提供快速的、無連線的通訊。 - 伺服器 socket 生命週期遵循:
socket()→bind()→listen()→accept()→recv()/send()→close()。 - Netcat(
nc)是測試 TCP 和 UDP 連線、傳輸檔案和連接埠掃描的必備命令列工具。 - Socket 選項如
SO_REUSEADDR、SO_KEEPALIVE和TCP_NODELAY允許針對特定應用程式需求微調 socket 行為。
下一步
在第 14 課中,您將學習路由與交換基礎——封包如何在網路之間轉發、路由表如何運作,以及 Linux 如何充當路由器。
日本語
概要
- 学習内容:ソケットの抽象化、Berkeley ソケット API、TCP と UDP ソケット、クライアント-サーバー通信パターン、Python と netcat によるハンズオン例。
- 前提条件:レッスン12 – IPアドレッシング、サブネット分割、CIDR
- 推定読了時間:22分
はじめに
ウェブサーバーやデータベースクライアントからチャットプログラムやIoTセンサーまで、すべてのネットワークアプリケーションはソケットを使用してネットワーク上でデータを送受信します。ソケットはIPアドレスとポート番号で識別される通信のエンドポイントです。アプリケーションコードと基盤となるTCP/IPプロトコルスタックの間のギャップを橋渡しする基本的な抽象化です。
ソケットAPIは1980年代初頭にBSD Unixの一部として開発され、その後すべての主要なオペレーティングシステムの標準ネットワークプログラミングインターフェースとなりました。ソケットを理解することは、Linuxでネットワークアプリケーションを構築、デバッグ、またはトラブルシューティングしたい人にとって不可欠です。
このレッスンでは、ソケットが概念レベルでどのように機能するかを学び、ソケットライフサイクルの主要なシステムコールを探索し、Pythonとnetcatなどのコマンドラインツールを使用した実践的な例を作成します。
ソケットとは?
ソケットは、サーバープロセスと1つ以上のクライアントプロセス間の双方向通信を確立するソフトウェアエンドポイントです。電話のようなものと考えてください——一方がダイヤルし(クライアントが接続)、もう一方が受話器を取ります(サーバーが受け入れ)。各ソケットはプロトコル(TCPまたはUDP)、ローカルIPアドレス、ローカルポート番号の組み合わせで一意に識別されます。
Linuxでは、ソケットはファイルディスクリプタとして表現されるため、標準的なファイル操作(read()やwrite())を使用してデータを送受信できます。これはUnixの「すべてはファイルである」という哲学と一致しています。
ソケットのライフサイクル
ソケットAPIは明確に定義されたシステムコールのシーケンスに従います。TCP接続の場合、サーバーとクライアントは異なるが補完的なパスに従います:
サーバー側:socket() → bind() → listen() → accept() → recv()/send() → close()
クライアント側:socket() → connect() → send()/recv() → close()
TCP と UDP ソケット
TCPソケット(SOCK_STREAM)は信頼性の高い、順序付けられた、コネクション指向の通信を提供します。UDPソケット(SOCK_DGRAM)は高速で、コネクションレスの、ベストエフォート配信を提供します。選択はアプリケーションの要件によって異なります。
Netcat によるハンズオン
Netcat(nc)はネットワークの「スイスアーミーナイフ」です。コマンドラインからTCPおよびUDP接続を作成でき、ソケットベースのサービスのテストとデバッグに非常に役立ちます。
ソケットオプションとチューニング
ソケットオプションを使用すると、ソケットの動作を微調整できます。一般的なオプションには、SO_REUSEADDR(アドレスの再利用を許可)、SO_KEEPALIVE(デッド接続の検出)、TCP_NODELAY(低レイテンシアプリケーション用にNagleアルゴリズムを無効化)があります。
重要ポイント
- ソケットはプロトコル、IPアドレス、ポート番号で識別される通信エンドポイントであり、すべてのネットワークアプリケーションの基本的な構成要素です。
- TCPソケット(
SOCK_STREAM)は信頼性の高い順序付き配信を提供し、UDPソケット(SOCK_DGRAM)は高速でコネクションレスの通信を提供します。 - サーバーソケットのライフサイクル:
socket()→bind()→listen()→accept()→recv()/send()→close()。 - Netcat(
nc)はTCPおよびUDP接続のテスト、ファイル転送、ポートスキャンに不可欠なコマンドラインツールです。 SO_REUSEADDR、SO_KEEPALIVE、TCP_NODELAYなどのソケットオプションにより、特定のアプリケーションニーズに合わせてソケットの動作を微調整できます。
次のステップ
レッスン14では、ルーティングとスイッチングの基礎を学びます——パケットがネットワーク間でどのように転送されるか、ルーティングテーブルの仕組み、Linuxがルーターとしてどのように機能するかを学びます。