目录
[sendto(发送函数)------- 先发](#sendto(发送函数)------- 先发)
[recvfrom(接收函数)------ 先收](#recvfrom(接收函数)------ 先收)
基于UDP协议的编程
编程模型:C/S

特点
- 无连接
- 不可靠
- 数据报
udp客户端流程
socket

bind(可选)

sendto(发送函数)------- 先发
**ssize_t****send(**int sockfd, const void *buf, size_t len, int flags);
ssize_tsendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
功能
- 将数据发送到指定的地址上
参数
- sockfd:进行发送用到的socket的fd
- buf:要发送的数据
- len:要发送的数据的长度
- flags:标志,默认写0表示默认发送方式
- dest_addr:表示要发送到的目的地址
- addrlen:表示目的地址的大小
返回值
- 成功返回 发送出去了的字节个数
- 失败返回 -1并且errno被设置
udp服务端流程
socket_udp
eg:int fd = socket(AF_INET,SOCK_DGRAM,0);

bind

recvfrom(接收函数)------ 先收
ssize_trecv(int sockfd, void *buf, size_t len, int flags);
ssize_trecvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
功能
- 接收数据
参数
- sockfd:进行发送用到的socket的fd
- buf:接收到的数据存放的位置
- len:要接收多少个字节的长度
- flags:标志,默认写0表示默认发送方式
- dest_addr:表示接收到的 源地址
- addrlen:表示值结果参数,用的时候初始化为 实际用到 src_addr类型的大小,函数返回将会带出真正src_addr地址的大小
返回值
- 成功返回 接收到的的字节个数
- 失败返回 -1并且errno被设置
练习1

udp_client.c
cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string.h>
int main(int argc, const char *argv[])
{
//1.socket
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd < 0)
{
perror("socket fail");
return -1;
}
//服务器的地址信息
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
seraddr.sin_port = htons(50000);
//2.sendto
char buf[1024];
while(1)
{
printf("client>");
fgets(buf,sizeof(buf),stdin);
sendto(fd,buf,strlen(buf)+1,0,(struct sockaddr *)&seraddr,sizeof(seraddr));
recvfrom(fd,buf,sizeof(buf),0,NULL,NULL);
printf("buf:%s\n",buf);
}
return 0;
}
udp_server.c
cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string.h>
int main(int argc, const char *argv[])
{
//1.socket
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd < 0)
{
perror("socket fail");
return -1;
}
//2.bind
//服务器的地址信息
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
seraddr.sin_port = htons(50000);
if(bind(fd,(const struct sockaddr*)&seraddr,sizeof(seraddr)) < 0)
{
perror("bind fail");
return -1;
}
//3.recvfrom
char buf[1024];
char sbuf[1024];
struct sockaddr_in srcaddr;
bzero(&srcaddr,sizeof(srcaddr));
socklen_t len = sizeof(srcaddr);
while(1)
{
recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&srcaddr,&len);
printf("buf:%s\n",buf);
sprintf(sbuf,"ser:%s",buf);
sendto(fd,sbuf,strlen(sbuf)+1,0,(struct sockaddr *)&srcaddr,len);
}
return 0;
}
练习2

udp_client.c
cpp
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
int fd = 0;
struct sockaddr_in seraddr;
char buf[1024] = "hello udp!";
pthread_t tid[2];
void * do_send (void *arg)
{
while(1)
{
printf(">");
fgets(buf,sizeof(buf),stdin);
sendto(fd,buf,strlen(buf)+1,0,(struct sockaddr *)&seraddr,sizeof(seraddr));
if (strncmp(buf,"quit",4) ==0)
break;
}
pthread_cancel(tid[1]);
return NULL;
}
void * do_recv (void *arg)
{
while(1)
{
char rbuf[1024] = {0};
recvfrom(fd,rbuf,sizeof(rbuf),0,NULL,NULL);
printf("recv buf = %s\n",rbuf);
if (strncmp(rbuf,"quit",4) ==0)
{
break;
}
}
pthread_cancel(tid[0]);
return NULL;
}
int main(int argc, const char *argv[])
{
//1.socket
fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("socket fail");
return -1;
}
//2.sendto
//服务器的地址信息
bzero(&seraddr,sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
seraddr.sin_port = htons(50000);
//创建线程
int ret = pthread_create(&tid[0],NULL,do_send,NULL);
if (ret !=0 )
{
errno = ret;
perror("pthread_create fail");
return -1;
}
ret = pthread_create(&tid[1],NULL,do_recv,NULL);
if (ret !=0 )
{
errno = ret;
perror("pthread_create fail");
return -1;
}
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
close(fd);
return 0;
}
udp_server.c
cpp
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
struct sockaddr_in srcaddr;
int fd;
char buf[1024] = "hello udp!";
pthread_t tid[2];
void * do_send (void *arg)
{
while(1)
{
printf(">");
fgets(buf,sizeof(buf),stdin);
sendto(fd,buf,strlen(buf)+1,0,(struct sockaddr *)&srcaddr,sizeof(srcaddr));
if (strncmp(buf,"quit",4) ==0)
{
break;
}
}
pthread_cancel(tid[1]);
return NULL;
}
void * do_recv (void *arg)
{
while(1)
{
char rbuf[1024] = {0};
recvfrom(fd,rbuf,sizeof(rbuf),0,NULL,NULL);
printf("recv buf = %s\n",rbuf);
if (strncmp(rbuf,"quit",4) ==0)
{
break;
}
}
pthread_cancel(tid[0]);
return NULL;
}
int main(int argc, const char *argv[])
{
//1.socket
fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("socket fail");
return -1;
}
//2.bind
//服务器的地址信息
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
seraddr.sin_port = htons(50000);
if (bind (fd,(const struct sockaddr*)&seraddr,sizeof(seraddr)) < 0)
{
perror("bind fail");
return -1;
}
//3.recvfrom
char buf[1024];
socklen_t len = sizeof(srcaddr);
bzero(&srcaddr,sizeof(srcaddr));
recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&srcaddr,&len);
printf("-----clinet info------\n");
printf("client ip = %s\n",inet_ntoa(srcaddr.sin_addr));
printf("client port = %d\n",ntohs(srcaddr.sin_port));
printf("buf = %s\n",buf);
//创建线程
int ret = pthread_create(&tid[0],NULL,do_send,NULL);
if (ret !=0 )
{
errno = ret;
perror("pthread_create fail");
return -1;
}
ret = pthread_create(&tid[1],NULL,do_recv,NULL);
if (ret !=0 )
{
errno = ret;
perror("pthread_create fail");
return -1;
}
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
close(fd);
return 0;
}