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; }