自修之道莫難於養心!
11. 套接字編程 (Socket)
11.1 UDP (User Datagram Protocol) 用戶數據報協議
11.1.1 流程
- 客戶端
1. 創建 socket 文件描述符
int socket(int domain, int type, int protocol);
domain: 地址域,AF_INET_IPV4地址域
type: 套接字類型 socket_STEAM: 流式套接字 socket_DGRAM: 數據報套接字
protocol: 傳輸層協議類型 0–默認 IPPROTO_IPC 6 IPPROTO_udp 17
返回值: 套接字操作句柄–文件描述符
2. 綁定端口號 (客戶端不推薦主動綁定,發送數據的時候能夠表述從哪個端口號發送出去,
回覆數據時就會再回復到這個地址端口上)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3.發送數據(將data中dlen長度的數據通過sockfd對應的socket結構中的ip/端口將數據發
送到dest_addr地址的主機上)
sendto(sockfd,data,dlen,flag,dest_addr,addr_len);
4.接受數據(從socket對應的socket結構體中的接受隊列中取出一條數據放到buf中)
recvfrom(sockfd,buf,len,flag,&peer_addr,&addr_len);
5.關閉套接字
int close(); - 服務端
1. 創建 socket 文件描述符
int socket(int domain, int type, int protocol);
2. 綁定端口號 (客戶端不推薦主動綁定,發送數據的時候能夠表述從哪個端口號發送出去,
回覆數據時就會再回復到這個地址端口上)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3.接受數據(從socket對應的socket結構體中的接受隊列中取出一條數據放到buf中)
recvfrom(sockfd,buf,len,flag,&peer_addr,&addr_len);
4.發送數據(將data中dlen長度的數據通過sockfd對應的socket結構中的ip/端口將數據發
送到dest_addr地址的主機上)
sendto(sockfd,data,dlen,flag,dest_addr,addr_len);
5.關閉套接字
int close();
11.1.2 適用場景
實時性要求極高, 但是安全性要求不是很高的場景 (例如視頻傳輸)
11.1.3 特點
傳輸層協議, 無連接, 不可靠傳輸, 面向數據報
11.2 TCP (Transmission Control Protocol) 傳輸控制協議
11.2.1 流程
- 客戶端
1. 創建 socket 文件描述符
int socket(int domain, int type, int protocol);
2. 綁定端口號 (客戶端不推薦主動綁定,發送數據的時候能夠表述從哪個端口號
發送出去,回覆數據時就會再回復到這個地址端口上)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3.向服務端發起連接請求
connect(socketfd,srv_addr,addrlen);
4.發送數據(將data中dlen長度的數據通過sockfd對應的socket結構中的ip/端口將
數據發送到dest_addr地址的主機上)
sendto(sockfd,data,dlen,flag);
5.接受數據(從socket對應的socket結構體中的接受隊列中取出一條數據放到buf中)
recvfrom(sockfd,buf,dlen,flag);
6.關閉套接字
int close(); - 服務端
1. 創建 socket 文件描述符
int socket(int domain, int type, int protocol);
2. 綁定端口號 (客戶端不推薦主動綁定,發送數據的時候能夠表述從哪個端口號
發送出去,回覆數據時就會再回復到這個地址端口上)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
3. 開始監聽(告訴操作系統若是有的新的客戶端連接請求過來了,就是爲這個客戶端
完成三次握手建立連接的過程);
backlog: 客戶端的最大併發連接數
listen(sockfd,int backlog);
4. 獲取已完成連接
5. 通過獲取的已完成連接socket接收數據
6. 通過獲取得已完成連接socket發送數據
7. 關閉套接字
int close();
11.2.2 適用場景
安全性要求極高的場景 (文件傳輸)
11.2.3 特點
傳輸層協議, 有連接, 可靠傳輸, 面向字節流
11.2.4 TCP服務端缺陷
TCP服務端爲每個客戶端都新建套接字進行獨立通信, 但是服務端無法獲知哪個客戶端數據會先
到來, 因此可能會阻塞在等待連接請求或者等待接收某個客戶端數據.
11.2.5 解決方案
- 多進程, 多線程任務處理;
- 每個線程,進程獨立負責一個功能;
- 一個線程,進程複製客戶端已完成連接獲取功能;
- 爲每個客戶端都建立一個線程,進程處理獨立通信.