UDP(User Datagram Protocol,用戶數據報協議)是一個簡單的、面向數據報的無鏈接協議,提供了快速但不必定可靠的傳輸服務。編程
UDP與TCP相比主要有如下區別。網絡
1.UDP速度比TCP快socket
因爲UDP不須要先與對方創建鏈接,也不須要傳輸確認,所以其數據傳輸速度比TCP快得多。ide
2.UDP有消息邊界函數
使用UDP不須要考慮消息邊界問題,使用上比TCP簡單spa
3.UDP能夠一對多傳輸3d
利用UDP可使用廣播或組播的方式同時向子網上的全部客戶發送信息。這一點也比TCP方便。指針
4.UDP可靠性不如TCPrest
與TCP不一樣,UDP並不提供數據傳送的保證機制。若是在從發送方到接收方的傳遞過程當中出現數據報的丟失,協議自己並不能作出任何檢測或提示。所以,一般人們把UDP稱爲不可靠的傳輸協議。orm
5.UDP不像TCP那樣能保證有序傳輸
UDP不能確保數據的發送和接收順序。對於突發性的數據報,有可能會亂序。事實上,UDP的這種亂序性基本上不多出現,一般只會在網絡很是擁擠的狀況下才有可能發生
1)建立socket時,數據格式爲:SOCK_DGRAM(數據塊)
2)數據收發用recvfrom和sendto
ssize_t recvfrom(int socket,void *restrict buffer,size_t length,int flags,struct sockaddr * restrict address,socklen_t *restrict address_len);
restrict:類型限定符,限定約束指針。代表該指針是訪問這個數據隊形的惟一的方式
補充一點:
void *memcpy( void * restrict dest ,const void * restrict src,sizi_t n) 這是一個頗有用的內存複製函數,因爲兩個參數都加了restrict限定,因此兩塊區域不能重疊,即 dest指針所指的區域,不能讓別的指針來修改,即src的指針不能修改. 相對應的別一個函數 memmove(void *dest,const void * src,size_t)則能夠重疊。
socket: 已鏈接的套接字
buffer:接收數據的緩衝區
length:緩衝區長度
flags :調用操做方式
address:指向裝有源地址的緩衝區(傳出型參數)
address_len:指向源地址緩衝區的實際長度(傳入傳出型參數)
ssize_t sendto(int socket,const void*buffer,size_t length,int flags,struct sockaddr* dest_addr,socklen_t len);
socket:已鏈接套接字
buffer:包含待發送數據的緩衝區
length:buffer緩衝區數據的長度
flags:調用方式標誌位
dest_addr:指向目的套接字的地址
len:dest_addr所指地址的長度
代碼:
server.c
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #define SIZE 1024 int main(int argc,char *argv[]) { if(argc!=3) { printf("enter [IP],[PORT]\n"); } int fd=socket(AF_INET,SOCK_DGRAM,0); if(fd<0) { perror(socket); return 1; } struct sockaddr_in local; int port=atoi(argv[2]); local.sin_family=AF_INET; local.sin_port=htons(port); local.sin_addr.s_addr=inet_addr(argv[1]); if(bind(fd,(struct socketaddr*)&local,sizeof(local))<0) { perror("bind"); return 2; } struct sockaddr_in remote; socklen_t len=sizeof(remote); while(1) { char buf[SIZE]; memset(buf,'\0',sizeof(buf)); ssize_t _s=recvfrom(fd,buf,sizeof(buf)-1,0,(struct socketaddr *)&remote,&len); if(_s>0) { buf[_s]='\0'; printf("client:[ip:%s][port:%d] %s",inet_ntoa(remote.sin_addr),ntohs(remote.sin_port)); } else if(_s==0) { printf("read done..\n"); break; } else{ break; } } close(fd); return 0; }
client.c
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> int main(int argc,char *argv[]) { if(argc!=3) { printf("[ip][port]\n"); return 1; } int fd=socket(AF_INET,SOCK_DGRAM,0); if(fd<0) { perror("socket"); return 2; } int port=atoi(argv[2]); struct sockaddr_in remote; remote.sin_family=AF_INET; remote.sin_port=htons(port); remote.sin_addr.s_addr=inet_addr(argv[1]); while(1) { char buf[1024]; memset(buf,'\0',sizeof(buf)-1); ssize_t _ss=read(0,buf,sizeof(buf)-1); if(_s>0) { buf[_s]='\0'; } ssize_t _s=sendto(fd,buf,sizeof(buf)-1,0,(struct sockaddr *)&remote,sizeof(remote)); } return 0; }