| 特性 | TCP (SOCK_STREAM) | UDP (SOCK_DGRAM) |
|---|---|---|
| 連接模式 | 面向連接(三次握手) | 無連接 |
| 可靠性 | 保證數據正確、有序、無重複 | 不保證,可能丟包、亂序、重複 |
| 數據邊界 | 流模式(無邊界,需應用層分幀) | 數據報模式(保留邊界) |
| 系統開銷 | 較大(連接維護、確認重傳) | 較小 |
| 適用場景 | 文件傳輸、郵件、Web、資料庫 | 即時通訊、視訊流、DNS、SNMP、廣播 |
| 編程關鍵差異 | listen/accept、connect 確定地址 | 無 listen/accept,sendto/recvfrom 每次攜帶地址 |
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv = {AF_INET, htons(6000), htonl(INADDR_ANY)};
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
listen(sockSrv, 5);
while (1) {
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
send(sockConn, "Welcome...", ..., 0);
recv(sockConn, recvBuf, 100, 0);
closesocket(sockConn);
}
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv = {AF_INET, htons(6000), inet_addr("127.0.0.1")};
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
recv(sockClient, recvBuf, 100, 0);
send(sockClient, "This is client", ..., 0);
closesocket(sockClient);
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);
// 無需 accept,直接從 addrClient 獲取發送方地址
SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv = {AF_INET, htons(6000), inet_addr("127.0.0.1")};
sendto(sockClient, "Hello", ..., 0, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
// 無需 connect,每次發送指定目標地址
socket():TCP 用 SOCK_STREAM,UDP 用 SOCK_DGRAM。listen() 和 accept()。connect()/accept() 返回的連接套接字。sendto()/recvfrom() 每次調用必須顯式傳遞 SOCKADDR_IN。shutdown() 對 UDP 無效(無連接狀態)。滿足以下條件優先考慮 UDP: