UDP全称是用户数据报协议,是一种无连接的传输协议。相比于TCP它的优缺点:
优点:传输速度快、资源消耗小、编程简单,在音视频数据传输中常用。
缺点:网络质量不好时,丢包严重、会照成数据丢失、损毁。
因为UDP是无连接的,所以通信流程会略有不同:
从图可以看出,使用UDP进行通信不需要双方建立连接就可以直接进行通信。
使用UDP进行网络编程,Linux另外提供了一些函数。
这个是在UDP模式下使用的数据发送函数,与TCP模式的区别就是每次发送都需要目标的地址等信息。
函数原型:
#include
#include
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
参数说明:
函数原型:
#include
#include
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
参数说明:
其他函数参看前面的博客:
#include
#include
#include
#include
#include
#include
typedef struct sockaddr* saddrp;
int main(int argc, char const *argv[])
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if (0 > sockfd)
{
perror("socket");
return -1;
}
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
socklen_t addr_len = sizeof(struct sockaddr_in);
while(1)
{
char buf[255] = {};
printf("Please input cData:");
gets(buf);
sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&addr,sizeof(addr));
if(0 == strncmp(buf, "end", 3)) break;
recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&addr,&addr_len);
printf("cRecv:%s\n",buf);
printf("the ipaddr = %#x\n", addr.sin_addr.s_addr);
printf("the port = %d\n", addr.sin_port);
if(0 == strncmp(buf, "end", 3)) break;
}
close(sockfd);
return 0;
}
#include
#include
#include
#include
#include
#include
typedef struct sockaddr* saddrp;
int main(int argc, char const *argv[])
{
//创建socket
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if (0 > sockfd)
{
perror("sockfd");
return -1;
}
//准备地址
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;//ipv4
addr.sin_port = htons(12345);//端口号
addr.sin_addr.s_addr = htonl(INADDR_ANY);//自动获取ip
//绑定
int ret = bind(sockfd,(saddrp)&addr,sizeof(addr));
if (0 > ret)
{
perror("bind");
return -1;
}
struct sockaddr_in src_addr ={};
socklen_t addr_len = sizeof(struct sockaddr_in);
while(1)
{
char buf[255] = {};
//接收数据和来源的ip地址
recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&src_addr,&addr_len);
printf("sRecv:%s\n",buf);
if (0 == strncmp(buf,"end",3)) break;
//发送数据给目标地址
printf("Please input sData to send:");
gets(buf);
sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&src_addr,addr_len);
if (0 == strncmp(buf,"end", 3)) break;
}
//关闭socket对象
close(sockfd);
return 0;
}
客户端先发送数据给服务器,服务区获取到数据后知道客户端的地址信息,就可以向客户端发送数据了,一般都是客户端先发送,服务器先接收。输入end会两边都会判断进行结束。