UDP协议、广播、组播和多路复用(网络编程二)
一、udp通信
1. 基本流程
| socket() | socket() |
| bind(); | bind(); |
| sendto/recvfrom | sendto/recvfrom |
| close() | close() |
注意: udp通信雙方,誰先發送的,誰就是發送端
2.相關接口函數
(一)發送信息
#include <socket.h>ssize_t sendto(int socket, void *message, size_t length, int flags, struct sockaddr *dest_addr,socklen_t dest_len); 返回值:length寫成多少,返回值就是多少參數:前面三個參數跟write一樣的flags --- 設置為0dest_addr --- 存放對方的ip和端口號dest_len --- 地址結構體大小(二)接收信息
#include <socket.h>ssize_t recvfrom(int socket, void *buffer, size_t length,int flags, struct sockaddr *address,socklen_t *address_len); 返回值:只要sendto發送的字節數不超過length,sendto發送多少,接收多少如果sendto發送的字節數超過length,就按照length的大小接收參數:前面三個參數跟read一樣的flags --- 設置為0address --- 存放對方的ip和端口號address_len --- 結構體大小,要求是指針3. 總結ip和端口號轉換的常用函數
(一)小端序(主機字節序) -> 大端序(網絡字節序)
(1)第一個
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>in_addr_t inet_addr(const char *cp); 返回值:成功 --- 返回轉換得到大端序二進制ip失敗 --- -1參數:cp --- 你需要轉換的點分十進制小端序ip(2)第二個
#include <arpa/inet.h>int inet_pton(int af, const char *src, void *dst); 參數:af --- 地址協議類型 AF_INETsrc --- 字符串ipdst --- 保存轉換得到的大端序ip(3)第三個
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>int inet_aton(const char *cp, struct in_addr *inp); 參數:cp --- 字符串ipinp --- 保存轉換得到的大端序ip(4)第四個
#include <arpa/inet.h>uint32_t htonl(INADDR_ANY);//改宏定義見TCP協議綁定(二)大端序(網絡字節序) -> 小端序(主機字節序)
(1)第一個
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>char *inet_ntoa(struct in_addr in); 返回值:轉換得到的字符串ip(小端序)失敗 --- -1參數:in --- 大端序ip(2)第二個
#include <arpa/inet.h>const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 返回值:轉換得到的小端序字符串ip參數:af --- 地址協議類型 AF_INETsrc --- 你要轉換的大端序ipdst --- 存放轉換得到的小端序字符串ipsize --- ip地址的大小4. udp廣播和udp的組播
廣播: 把信息發送給該網段中所有的主機
ip地址分類:A B C D 四類ip地址
流程:
| socket | socket |
| bind 注意必須使用INADDR_ANY | bind 注意必須使用INADDR_ANY |
| 設置套接字的屬性為可以廣播 | |
| 收發信息 | 收發信息 |
| close | close |
(一)設置udp套接字可以廣播
int on=1; setsockopt(udp套接字,SOL_SOCKET, SO_BROADCAST ,&on,sizeof(on));(二) udp組播
組播是廣播一種特殊形式,廣播是發送信息給所有主機,組播僅僅只是發送給一小部分主機,單播是一對一的
流程:
| socket | socket |
| bind 注意必須使用INADDR_ANY | bind 注意必須使用INADDR_ANY |
| 設置套接字的屬性為可以廣播 | 加入到組播組里面 |
| 收發信息 | 收發信息 |
| close | close |
重點代碼:
//加入組播組 struct ip_mreq mreq; //存放組播地址的結構體變量 bzero(&mreq, sizeof(mreq)); mreq.imr_multiaddr.s_addr = inet_addr("224.168.11.10"); //D類地址,必須跟sendto一致 mreq.imr_interface.s_addr = htonl(INADDR_ANY); // 必須用這個宏定義 setsockopt(udpsock, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof mreq); //設置加入到組播組里面5. tcp和udp的區別(理論知識)
TCP是面向連接的可靠的通信方式
面向連接: TCP客戶端和服務器在通信之前是必須經歷三次握手TCP協議底層幫我們去完成,程序員是感受不到的,理論分析)
三次握手: 發生在TCP建立連接的時候
四次握手: 發生在TCP斷開連接的時候
可靠: TCP協議支持錯誤校驗和錯誤重傳,不容易丟失數據包,用于通信要求嚴格的場合(發送賬號,密碼,占用的網絡帶寬資源比較大)
UDP是無連接的不可靠的通信方式
不可靠:UDP協議沒有錯誤重傳,網絡擁堵情況下容易丟失數據包(視頻點播,占用的網絡帶寬資源要小)
二、多路復用
1. 引用及概念
多路復用: 幫助我們去監控網絡中IO通道中數據的流入和流出的
每個IO通道又對應一個文件描述符,所有最終可以認為幫助我們去監控網絡中文件描述符是否有數據可讀(I),是否有數據可寫(O)
linux中定義了一個變量類型,名字fd_set,專門幫助我們存放所有需要監測的文件描述符
fd_set類型: 專業術語稱作文件描述符集合第一步: 定義fd_set類型變量存放需要監測的文件描述符
fd_set myset;第二步:往集合變量中存放你想監測的文件描述符
void FD_CLR(int fd, fd_set *set); //將fd從集合中刪除 int FD_ISSET(int fd, fd_set *set); //判斷fd在不在set集合中 在 --- 返回1 不在 --- 返回0 void FD_SET(int fd, fd_set *set); //將fd添加到set集合中 void FD_ZERO(fd_set *set); //清空set集合 FD_ZERO(&myset); FD_SET(fd1, &myset); FD_SET(fd2, &myset); FD_SET(fd3, &myset);第三步:調用select去監控剛才的三個文件描述符
select(最大+1,&myset,NULL,NULL,NULL); //監測讀就緒 select(最大+1,NULL,&myset,NULL,NULL); //監測寫就緒第四步:判斷究竟是哪個文件描述符發生了狀態改變(讀就緒,寫就緒,異常就緒)
select的特點:
①如果監測了ABC三個文件描述符,A發生了狀態改變,select就會自動把沒有發生狀態改變的BC從集合中刪除
換句話來說:select只保留狀態發生改變的文件描述符
②select會阻塞,直到監測到某個文件描述符發生了狀態改變才不會阻塞
2. 相關的接口函數
#include <sys/select.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h>int select(int nfds, fd_set *readfds, fd_set *restrict writefds, fd_set *restrict errorfds,struct timeval *restrict timeout); 返回值: 成功 >0失敗 -1超時 0參數:nfds(重點) --- 你要監測的所有IO通道(文件描述符)中最大的文件描述符+1readfds --- 監測集合中文件描述符是否有數據可讀(讀就緒)writefds --- 監測集合中文件描述符是否有數據可寫(寫就緒)errorfds --- 監測集合中文件描述符是否發生了異常(異常就緒)timeout --- 超時,一般設置為NULL表示永遠等待struct timeval {tv_sec; //秒tv_usec; //微秒}總結
以上是生活随笔為你收集整理的UDP协议、广播、组播和多路复用(网络编程二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5款国产ARM芯片替代ST
- 下一篇: FT232RL变砖之后