什麼是 Socket ?

1
什麼是 Socket ?:Socket(插座)是網路程式設計中的核心抽象概念,表示網路通訊的端點(endpoint),由 IP 位址與埠號(Port)組成,用於在不同主機或程序間建立雙向資料通道。它封裝了底層 TCP/UDP 通訊細節,提供 connect()、send()、receive() 等 API,讓應用程式能像操作檔案般處理網路 I/O,是 Web 伺服器、即時通訊、遊戲伺服器等網路應用的基礎。

什麼是 Socket ?

Socket(插座)是網路程式設計中的核心抽象概念,表示網路通訊的端點(endpoint),由 IP 位址與埠號(Port)組成,用於在不同主機或程序間建立雙向資料通道。它封裝了底層 TCP/UDP 通訊細節,提供 connect()send()receive() 等 API,讓應用程式能像操作檔案般處理網路 I/O,是 Web 伺服器、即時通訊、遊戲伺服器等網路應用的基礎。

 

Socket 的本質與結構

Socket 是作業系統提供的介面,將網路協議轉換為應用程式可用的檔案描述符:

Socket = (IP 位址, 埠號, 通訊協定)
範例:(192.168.1.100, 8080, TCP)

四元組唯一識別連線:
(來源IP:埠, 目的IP:埠) = (192.168.1.100:54321, 93.184.216.34:80)
 

Socket 在 OS 中的角色

應用程式 → socket() API → 核心網路堆疊 → 網卡 → 網路
檔案描述符(fd) ↔ sock 結構體 ↔ sk_buff 封包佇列
 

TCP vs UDP Socket 比較

特性 TCP Socket UDP Socket
連線型態 有連線(三次握手) 無連線(直接發送)
資料保證 可靠、有序、重傳 盡力送達、無序
效能 較慢(狀態維護) 快速(無狀態)
API connect()listen()accept() sendto()recvfrom()
用途 Web、郵件、檔案傳輸 串流、DNS、遊戲

 

TCP Socket 程式設計完整範例

服務端(Python)

import socket

# 1. 建立 Socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. 綁定位址與埠號
server.bind(('0.0.0.0', 8080))  # 監聽所有介面

# 3. 監聽連線(連線佇列長度)
server.listen(5)
print("伺服器啟動,監聽 8080 埠...")

while True:
    # 4. 接受連線,返回新 Socket 與客戶端位址
    client_socket, addr = server.accept()
    print(f"客戶端連線:{addr}")
    
    # 5. 接收資料
    data = client_socket.recv(1024)
    print(f"收到:{data.decode()}")
    
    # 6. 發送回應
    client_socket.send(b"HTTP/1.1 200 OK Hello World!")
    
    # 7. 關閉連線
    client_socket.close()

server.close()
 

客戶端(Python)

import socket

# 1. 建立 Socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. 連線到伺服器
client.connect(('127.0.0.1', 8080))

# 3. 發送資料
client.send(b"GET / HTTP/1.1 Host: localhost ")

# 4. 接收回應
response = client.recv(4096)
print(response.decode())

# 5. 關閉 Socket
client.close()

 

Socket 生命週期

服務端生命週期

socket() → bind() → listen() → [accept() → 處理 → close()] 重複 → close()
 

客戶端生命週期

socket() → connect() → send()/recv() → close()
 

連線狀態機(TCP):

CLOSED → LISTEN(服務端)
       ↓ SYN
SYN_SENT(客戶端) ↔ SYN_RCVD(服務端)
       ↓ ACK
       ESTABLISHED(資料傳輸)
       ↓ FIN
FIN_WAIT → CLOSE_WAIT → LAST_ACK → CLOSED
 

非阻塞與多工 Socket

同步阻塞(預設)

python

data = sock.recv(1024) # 阻塞直到有資料

非阻塞 Socket

import socket
import select

sock.setblocking(False)

# I/O 多工:select/poll/epoll
readable, _, _ = select.select([sock], [], [], 1.0)
if sock in readable:
    data = sock.recv(1024)
 

現代多工方案

select():檔案描述符位元遮罩,O(n)
poll():  陣列結構,無 1024 限制
epoll(): Linux 事件驅動,O(1),Node.js/io_uring 基礎
kqueue():BSD/Mac,高效事件通知
 

WebSocket vs 傳統 Socket

HTTP 輪詢問題

客戶端 → Poll /messages → 無新訊息 → 1 秒後重試 → 重複
 

WebSocket 解決方案

握手:HTTP Upgrade: websocket
資料:Frame[Opcode(FIN|Text|Binary)][Payload]
雙向:全雙工,伺服器主動推送
 

// 客戶端
const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = (event) => console.log(event.data);
ws.send('Hello Server!');

// 服務端(Node.js)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', ws => {
    ws.on('message', msg => ws.send(`Echo: ${msg}`));
});
 

Socket 程式設計最佳實務

錯誤處理

try:
    sock.connect((host, port))
except socket.timeout:
    print("連線超時")
except ConnectionRefusedError:
    print("連線被拒")
except OSError as e:
    print(f"網路錯誤:{e}")
finally:
    sock.close()

 

緩衝區管理

def recv_all(sock, chunk_size=1024):
    data = b""
    while True:
        chunk = sock.recv(chunk_size)
        if not chunk:  # 連線關閉
            break
        data += chunk
    return data

 

連線池與超時

sock.settimeout(5.0)  # 5 秒超時
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

 

常見 Socket 應用場景

應用 Socket 類型 埠號 範例
HTTP 伺服器 TCP 80/443 Nginx、Apache
SSH 遠端連線 TCP 22 OpenSSH
資料庫連線 TCP 5432(MySQL) PostgreSQL
即時通訊 WebSocket 自定义 ChatGPT、Discord
遊戲伺服器 UDP/TCP 7777 Unity、Unreal

 

跨語言 Socket 互通範例

Python 服務端 ↔ Go 客戶端

// Go 客戶端
conn, err := net.Dial("tcp", "127.0.0.1:8080")
if err != nil { panic(err) }
defer conn.Close()
conn.Write([]byte("Hello from Go!"))
reply := make([]byte, 1024)
n, _ := conn.Read(reply)
fmt.Println(string(reply[:n]))
 

Socket 是網路程式設計的基石,從簡單 TCP Echo 到複雜微服務網格,從 WebSocket 即時通訊到遊戲伺服器 UDP 廣播。理解 Socket API(bind/listen/accept/connect)與底層狀態機,就能打造任何網路應用。現代框架雖封裝細節,但核心仍是 Socket,掌握它等於掌握網路程式設計的本質!