UDP 是無連接協議,但 connect() 在 UDP 中**並非建立連接**,而是**在內核中記錄目標地址**,使後續 send()/write() 可省略目標地址參數。
| 屬性 | 設置函數 | 說明 |
|---|---|---|
| 協議族/類型 | socket(AF_INET, SOCK_DGRAM, 0) | 創建 UDP socket |
| 本地地址/端口 | bind() | 指定本地 IP/端口,或 INADDR_ANY 綁定所有接口 |
| 目標地址/端口 | connect() / sendto() 參數 | connect 後可用 send();未 connect 必須用 sendto() |
int sock = socket(AF_INET, SOCK_DGRAM, 0);
// 可選 bind() 指定源端口
struct sockaddr_in dst = { .sin_family=AF_INET, .sin_port=htons(8888), .sin_addr.s_addr=inet_addr("1.2.3.4") };
sendto(sock, buf, len, 0, (struct sockaddr*)&dst, sizeof(dst));
bind(),內核自動分配臨時端口 (1024–5000) 並隱式綁定。int sock = socket(AF_INET, SOCK_DGRAM, 0);
connect(sock, (struct sockaddr*)&dst, sizeof(dst)); // 僅記錄目標
send(sock, buf, len, 0); // 直接發送
// 可用 getsockname() 獲取本地綁定信息
connect() 不發送數據包,僅設置內核結構體。服務端調用 connect() 後,內核會**過濾非該目標地址的數據包**,實現「單客戶端鎖定」功能,可用於簡單的單播回應服務。
| 特性 | sendto | connect + send |
|---|---|---|
| 目標地址靈活性 | 每次可變 | 固定 (需重新 connect 修改) |
| 系統調用開銷 | 每次傳遞地址結構 | 僅首次 connect 有開銷 |
| 適用場景 | 多目標、廣播、組播 | 固定單播目標、簡化代碼 |
| 隱式綁定 | 首次 sendto 自動綁定臨時端口 | connect 前可顯式 bind 指定源端口 |
bind() 指定源端口 (便於防火牆放行) → connect() → send() 循環。bind() 固定端口 → recvfrom() 循環 (獲取客戶端地址) → sendto() 回覆。send() 返回 -1 且 errno=ECONNREFUSED 表示目標端口不可達 (ICMP Port Unreachable)。UDP 中 connect() 是「地址綁定捷徑」,非連接建立。善用 bind() 固定源端口、connect() 簡化發送、sendto() 保持靈活性,是高性能 UDP 編程關鍵。