- 一、網絡協議 UDP
- UDP用戶數據報協議:傳輸層
- 網絡編程模型
- B/S模型:browser/server(瀏覽器/服務器)
- 客戶端是通用的客戶端(瀏覽器)
- 一般只做服務器開發
- 客戶端要加載的數據均來自服務器
- C/S模型:client/server(客戶端/服務端)
- 客戶端是一個專用的客戶端
- 服務器和客戶端都需要開發
- 客戶端可保存資源,本地加載,無需所有數據都請求服務器
- B/S模型:browser/server(瀏覽器/服務器)
- UDP編程流程
- 套接字:文件描述符(網絡通信時,應用層可操作的端口)
- 發送端
- socket:int socket(int domain, int type, int protocol
- 功能:創建通信的套接字
- 參數:
- domain:網絡層使用什么協議族
- AF_INET: IPv4
- AF_INET6:IPv6
- type:規定傳輸層的協議
- SOCK_DGRAM:UDP協議
- SOCKSTREAM:TCP協議
- SOCKRAW:原始套接字
- protocol:0 按照默認協議方式創建
- domain:網絡層使用什么協議族
- 返回值:成功:套接字;失敗:-1
- sendto:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen)
- 功能:向網絡套接字發送數據
- 參數:sockfd:套接字;buf:要發送的數據的首地址;len:要發送的字節數;flags:0:按照默認方式發送;dest_addr:接收方的地址信息(IP+端口號);addrlen:接收方地址的大小
- man 7 ip
- 返回值:成功:實際發送的字節數;失敗:-1
- 網絡字節序:大段
- 主機字節序:小段
- uint3 2_t htonl(uint32_t hostlong);主機轉網絡
- uint1 6_t htons(uint16_t hostshort);主機轉網絡
- uint3 2_t ntohl(uint32_t hostlong);網絡轉主機
- uint1 6_t ntohs(uint16_t hostshort);網絡轉主機
- in_addr_t inet _addr(const char *cp);
- 功能:將字符串IP地址轉換成二進制IP地址形式
- char *inet _ntoa(struct in_addr in);
- 功能:將二進制ip轉換成字符串
- socket:int socket(int domain, int type, int protocol
- 接收端
- bind:int bind(int sockfd, const struct sockaddr *addr.socklen_t addrlen);
- 功能:綁定自己的IP地址和端口號
- 參數:sockfd:套接字;addr:需要綁定的地址;adlrlen:地址大小
- 返回值:成功:0;失敗:-1
- recvfrom:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen)
- 功能:從套接字上接收數據
- 參數:sockfd:套接字;buf:存放接收數據的內存首地址;len:希望接收的字節數;flags:0:按照默認方式接收(阻塞);src_addr:發送方的地址信息;addrlen:發送發地址的指針
- 返回值:成功:實際接收到的字節數;失敗:-1
- bind:int bind(int sockfd, const struct sockaddr *addr.socklen_t addrlen);
- UDP特點
- 面向數據包
- 無需建立連接
- 盡最大努力交付,不安全、不可靠(數據丟包、亂序)
- 可實現一對一、一對多的傳輸
- 機制簡單,資源開銷小,數據傳輸實時性高(VNC、直播)
- 如何避免UDP丟包
- 發送方以較慢的速度發送數據,讓接收端有足夠的時間處理數據
- 模仿TCP的機制:應答機制
- 抓包工具 wireshark
- 網絡抓包:抓取通過設備網卡的網絡數據,從而調試和分析網絡程序
- 使用:
- sudo wireshark啟動抓包工具
- 選取要抓取的網卡---》any
- 選擇一個過濾條件
- 開始抓取
- 進行一次網絡通信
- UDP報文頭部 共8字節
- 源端口號:發送方網絡進程端口號
- 目標端口號:接收方網絡進程端口號
- 長度:UDP發送的報文的整體長度(UDP頭部
- 二、網絡協議 TCP
- TCP特點
- 面向數據流
- 有鏈接(通信之前必須建立鏈接)
- 安全可靠的傳輸機制
- 機制復雜、網絡資源開銷大
- 本質只能實現一對一的通信(使用TCP并發方式可實現一對多通信)
- TCP三次握手和四次揮手機制
- 三次握手
- TCP建立連接時,需要進行三次握手,為了確保收發雙方通信之前都已準備就緒
- SYN:請求建立鏈接標志位
- ACK:相應報文標志位
- TCP建立連接時,需要進行三次握手,為了確保收發雙方通信之前都已準備就緒
- 四次揮手
- TCP斷開連接時,需要進行四次揮手,確保斷開連接前雙方都已通信結束
- FIN:請求斷開連接標志位
- ACK:相應報文標志位
- 服務端在發送ACK、FIN之間依然可以傳輸數據
- TCP斷開連接時,需要進行四次揮手,確保斷開連接前雙方都已通信結束
- 三次握手
- TCP的編程流程
- 發送端
- connect :int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
- 功能:請求與服務端建立連接
- 參數:sockfd:套接字;addr:要連接的服務端的地址信息;addrleqn:服務端地址大小
- 返回值:成功:0;失敗:-1
- send :ssize_t send(int sockfd, const void *buf, size_t len, int flags)
- 功能:發送網絡數據
- 參數:sockfd:網絡套接字;buf:要發送的數據首地址;len:發送的字節數;flags:0:按照默認方式發送
- 返回值:成功:實際發送的字節數;失敗:-1
- connect :int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
- 接收端
- listen :int listen(int sockfd, int backlog);
- 功能:監聽建立三次握手的客戶端
- 參數:sockfd:監聽套接字;backlog:最大允許監聽的客戶端個數
- 返回值:成功:0;失敗:-1
- accept :int accept(int socket, struct sockaddr *restrict address,socklen_t *restrict address_len);
- 功能:接收建立三次握手的客戶端,并產生一個通訊套接字
- 參數:socket:監聽套接字;address:客戶端的地址信息;addresslen:客戶端地址長的指針
- 返回值:成功:通訊套接字;失敗:-1
- recv :ssize _t recv(int sockfd, void *buf, size_t len, int flags);
- 功能:從網絡套接字上接收數據
- 參數:sockfd:通訊套接字;buf:存放接收數據的首地址;len:期望接收到的字節數;flag:0:默認方式接收(阻塞)
- 返回值:成功:實際接收到的字節數;失敗:-1;對方斷開連接時:0
- listen :int listen(int sockfd, int backlog);
- 發送端
- TCP粘包問題
- 發送方應用層發送的多包數據,將來在接收方可能一次讀到,多包數據產生了粘連
- 原因:
- 發送方速度較快,TCP底層可能對多包數據進行重新組幀
- 接收方數據處理速度較慢,導致多包數據在接收緩沖區緩存,應用層讀時,一次將多包數據讀出
- 解決方法
- 調整發送速率
- 發送指定大小,接收方接收指定大小(結構體)
- 注意:跨平臺之間的數據傳輸時,注意結構體對齊問題
- 應用層為發送的數據增加分隔符,利用分隔符解析
- 封裝自定義數據幀格式進行發送(協議)
- TCP特點