一、概述
UDP協議簡單介紹:
1.UDP協議是用戶數據報協議,面向無連接的、不穩定、不可靠、不安全的數據報傳遞---更像是是收發短信。
2.UDP傳輸不需要建立連接,傳輸效率更高,在穩定的局域網內環境相對可靠
3.UDP天然支持多客戶端
C語言UDP函數介紹:
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 設置errno 調用該函數相當於TCP通信的recv+accept函數 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 函數說明: 發送數據 參數說明: sockfd 套接字 dest_addr 目的地址 addrlen 目的地址長度 返回值 成功: 返回寫入的字節數 失敗: 返回-1,設置errno
UDP通訊服務端具體步驟:
1.創建套接字,得到一個cfd
2.綁定端口
3.在while循環中收發數據 recvfrom/sendto
4.關閉套接字
UDP通訊客戶端操作步驟:
1.創建一個套接字,得到一個cfd
2.在while循環中收發數據recvfrom /sendto
3.關閉套接字
二、代碼示例
1.服務端代碼
//udp服務端(udp天生支持多客戶端) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <ctype.h> int main(int argc, char const *argv[]) { //1.創建socket int cfd = socket(AF_INET,SOCK_DGRAM,0); if(cfd<0){ perror("socket error"); return -1; } //綁定 struct sockaddr_in serv; struct sockaddr_in client; bzero(&serv,sizeof(serv)); serv.sin_family = AF_INET; serv.sin_port = htons(8888); serv.sin_addr.s_addr = htonl(INADDR_ANY); bind(cfd,(struct sockaddr *)&serv,sizeof(serv)); //3.循環讀取讀取客戶端消息和給客戶端回復消息 int i; int n; socklen_t len; char buf[1024]; while(1){ //4.讀取數據 memset(buf,0x00,sizeof(buf)); len = sizeof(client); n = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&client,&len); //將大寫轉換為小寫 for(i=0;i<n;i++){ buf[i] = toupper(buf[i]); } printf("[%d]:n=[%d],buf=[%s]\n",ntohs(client.sin_port),n,buf); //5.給客戶端回復消息 sendto(cfd,buf,n,0,(struct sockaddr*)&client,len); } //關閉套接字 close(cfd); return 0; }
2.客戶端代碼
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <ctype.h> int main(){ //1.創建socket int cfd = socket(AF_INET,SOCK_DGRAM,0); if(cfd<0){ perror("socket error"); return -1; } int n ; char buf[1024]; struct sockaddr_in serv; serv.sin_family = AF_INET; serv.sin_port = htons(8888); inet_pton(AF_INET,"127.0.0.1",&serv.sin_addr.s_addr); while(1){ //讀取標准輸入數據 memset(buf,0x00,sizeof(buf)); n = read(STDIN_FILENO,buf,sizeof(buf)); //發送數據 sendto(cfd,buf,n,0,(struct sockaddr*)&serv,sizeof(serv)); //讀取數據 memset(buf,0x00,sizeof(buf)); n = recvfrom(cfd,buf,sizeof(buf),0,NULL,NULL); printf("n=[%d],buf=[%s]\n",n,buf); } //關閉套接字 close(cfd); return 0; }
