一種無鏈接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務,它一旦把應用的程序發送給網絡層以後不保留數據的備份。可是由於沒有不少安全性的校驗使得它的傳輸速率特別的快。 UDP提供了無鏈接通訊,且不對傳送數據包進行可靠性保證,適合於一次傳輸少許數據,UDP傳輸的可靠性由應用層負責。c++
###所需的結構和方法 *sockaddr_in結構體安全
#include <netinet/in.h> struct sockaddr_in { short sin_family; // e.g. AF_INET unsigned short sin_port; // e.g. htons(3490) struct in_addr sin_addr; // see struct in_addr, below char sin_zero[8]; // zero this if you want to }; struct in_addr { unsigned long s_addr; // load with inet_aton() };
socket(int socket_family, int socket_type, int protocol);網絡
AF_UNIX,AF_LOCAL 本地通信dom
AF_INET IPV4網絡規約socket
AF_INET6 IPV6網絡規約tcp
SOCK_STREAM 提供可靠的鏈接方式(TCP)函數
SOCK_DGRAM 提供不可靠非鏈接的通信方式(UDP)this
IPPROTO_IP 至關於指定的參數爲零atom
IPPROTO_TCP 代表採用TCP規約指針
IPPROTO_UDP 表示採用UDP規約
####bind方法 bind標準定義是指綁定一個名稱到socket,sockfd是表示一個socket所建立的對象,sockaddr表示是該綁定的地址和socket所指向的地址分配空間大小
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
####recvfrom 接收一個數據報並保存源地址
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
該函數返回接收的字節數,若是出現錯誤返回-1,假若對方關閉鏈路則返回0;
socket()->bind()->recvfrom()->sendto()
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <arpa/inet.h> #include <sys/socket.h> #define BUFLEN 512//最大的緩衝長度 #define PORT 8888//監聽數據的端口 void die(char *s){ perror(s); exit(1); } int main(int argc, char const* argv[]) { struct sockaddr_in si_me,si_other; int s,i,slen=sizeof(si_other),recv_len; char buf[BUFLEN]; //建立一個UDP的socket if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1){ die("socket"); } //將這個結構清零 memset((char *)&si_me,0,sizeof(si_me)); si_me.sin_family=AF_INET; si_me.sin_port=htons(PORT); si_me.sin_addr.s_addr=htonl(INADDR_ANY); //指定須要綁定的端口 if(bind(s,(struct sockaddr*)&si_me,sizeof(si_me))==-1){ die("bind"); } while(1){ printf("Waiting for data..."); fflush(stdout); //從遠程接收數據,這是一個堵塞的函數,直到接觸到數據爲止 if((recv_len=recvfrom(s,buf,BUFLEN,0,(struct sockaddr*)&si_other,&slen))==-1) { die("recvfrom()"); } //打印客戶端的信息及其相關的信息 printf("Received packet from %s:%d\n",inet_ntoa(si_other.sin_addr),ntohs(si_other.sin_port)); printf("recv Data:%s\n",buf); //將接收到的數據進行發送 if(sendto(s,buf,recv_len,0,(struct sockaddr*)&si_other,slen)==-1){ die("sendto()"); } //重置全部的數據 bzero(&buf,sizeof(buf)); } close(s);//關閉socket return 0; }
Waiting for data...Received packet from 127.0.0.1:64687
recv Data:send data
socket()->sendto()/recvfrom()
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <arpa/inet.h> #include <sys/socket.h> #define SERVER "127.0.0.1" #define BUFLEN 512//緩衝區的大小 #define PORT 8888//發送數據的端口 void die(char *s){ perror(s); exit(1); } int main(int argc, char const* argv[]) { struct sockaddr_in si_other; int s,i,slen=sizeof(si_other); char buf[BUFLEN]; char message[BUFLEN]; if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) { die("socket"); } memset((char *)&si_other,0,sizeof(si_other)); si_other.sin_family=AF_INET; si_other.sin_port=htons(PORT); if(inet_aton(SERVER,&si_other.sin_addr)==0){ fprintf(stderr,"inet_atom() failed\n"); exit(1); } while(1){ printf("Enter message:"); gets(message); //發送數據 if(sendto(s,message,strlen(message),0,(struct sockaddr *)&si_other,slen)==-1){ die("sendto()"); } //接收發送的返回消息而且打印 //再將這個buffer進行清空 if(recvfrom(s,buf,BUFLEN,0,(struct sockaddr *)&si_other,&slen)==-1){ die("recvfrom()"); } puts(buf); bzero(&buf,sizeof(buf)); } close(s); return 0; }
warning: this program uses gets(), which is unsafe.
Enter message:send data
send data
Enter message: