與面向鏈接的協議相比,面向無鏈接協議極爲不一樣。其中一個重要的不一樣點就是客戶端與服務器之間沒必要創建鏈接。編程
對於UDP套接字編程而言,服務器建立套接字後,調用bind()函數將套接字與準備接收數據的接口綁定在一塊兒。和TCP編程不一樣的是,應用程序沒必要調用 listen()和accept()函數等待客戶端的鏈接。而只須要等待接收數據了。開發UDP套接字應用程序,有兩個重要的函數sendto()和 recvfrom()。服務器採用recvfrom()來接收來自客戶端的數據報,並得到客戶端的端地址,以後向客戶端發送數據時,採用sendto() 函數。服務器
下面是一個簡單的UDP服務器的實現:socket
//udp_server.c
ide
#include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> void usage(char *proc) { printf("%s [ip] [port]\n",proc); } int main(int argc,char *argv[]) { if(argc != 3) { usage(argv[0]); return 1; } int sock=socket(AF_INET,SOCK_DGRAM,0); if(sock<0) { perror("socket"); return 1; } int _port=atoi(argv[2]); char *_ip=argv[1]; struct sockaddr_in local; local.sin_family=AF_INET; local.sin_port=htons(_port); local.sin_addr.s_addr=inet_addr(_ip); if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) { perror("bind"); return 2; } char buf[1024]; struct sockaddr_in client; socklen_t client_len; while(1) { ssize_t _size=recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&client,&client_len); if(_size<0) { perror("recvfrom"); } else if(_size == 0) { printf("client shutdown ... \n"); } else { printf("client >> %s",buf); } } return 0; }
//udp_client.c函數
#include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> void usage(char *proc) { printf("%s [ip] [port] \n",proc); } int main(int argc,char *argv[]) { if(argc != 3) { usage(argv[0]); return 1; } int sock=socket(AF_INET,SOCK_DGRAM,0); if(sock<0) { perror("socket"); return 2; } int _port=atoi(argv[2]); char *_ip=argv[1]; struct sockaddr_in remote; remote.sin_family=AF_INET; remote.sin_port=htons(_port); remote.sin_addr.s_addr=inet_addr(_ip); socklen_t remote_len=sizeof(remote); char buf[1024]; while(1) { printf("Please Enter >> "); fgets(buf,sizeof(buf),stdin); ssize_t _size=sendto(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&remote,remote_len); if(_size<0) { perror("sendto"); } } return 0; }
運行結果:server