UDP通信相关函数:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
函数说明:接收信息
- 参数说明:
- sockfd:套接字
- buf:要接收的缓冲区
- len:缓冲区的长度
- flags:标志位,一般为0
- src_addr:传出参数,发送方的地址
- addrlen:发送方地址的长度
返回值:
成功返回读到的子节数
失败返回-1,并设置errno;
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
函数说明:发送数据
- sockfd:套接字
- buf:要发送的缓冲区
- len:缓冲区的长度
- flags:标志位,一般为0
- src_addr:传入参数,接收者的地址
- addrlen:接收者地址的长度
udp服务端代码:
(相比于tcp服务端,不用liseten,accept)
而且udp服务端可以同时接收多个客户端发来的数据。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include <netinet/in.h>
#include<ctype.h>
int main()
{
int cfd=socket(AF_INET,SOCK_DGRAM,0);
if(cfd<0)
{
perror("socket error");
return -1;
}
struct sockaddr_in serv;//
struct sockaddr_in cli;//定义一个客户端地址,用于接收发来数据的客户端地址
bzero(&serv,sizeof(serv));
bzero(&cli,sizeof(cli));
serv.sin_family=AF_INET;
serv.sin_port=htons(8888);
inet_pton(AF_INET,"192.168.230.130",&serv.sin_addr.s_addr);
bind(cfd,(struct sockaddr*)&serv,sizeof(serv));//绑定
char buf[128];
int n;
int i=0;
socklen_t len;
while(1)
{
len=sizeof(cli);
memset(buf,0x00,sizeof(buf));
n=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);//接收数据,并说的发送方的地址,端口
printf("port==[%d],n==[%d],buf==[%s]\n",ntohs(cli.sin_port),n,buf);
for(i=0;i<n;i++)
{
buf[i]=toupper(buf[i]);
}
sendto(cfd,buf,n,0,(struct sockaddr*)&cli,sizeof(cli));//发送数据
}
close(cfd);
return 0;
}
我们可以使用 nc -u 命令进行检测;
udp客户端代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include <netinet/in.h>
int main()
{
int cfd=socket(AF_INET,SOCK_DGRAM,0);
if(cfd<0)
{
perror("socket error");
return 0;
}
char buf[128];
struct sockaddr_in ser;
bzero(&ser,sizeof(ser));
ser. sin_family=AF_INET;
ser.sin_port=htons(8888);
inet_pton(AF_INET,"192.168.230.130",&ser.sin_addr.s_addr);
int n;
while(1)
{
memset(buf,0x00,sizeof(buf));
n= read(STDIN_FILENO,buf,sizeof(buf));//从标准输入读数据
sendto(cfd,buf,n,0,(struct sockaddr *)&ser,sizeof(ser));//向此地址发送数据
memset(buf,0x00,sizeof(buf));
n=recvfrom(cfd,buf,sizeof(buf),0,NULL,NULL);//不关心谁发的读数据,可以设为NULL
printf("n==[%d],buf==[%s]\n",n,buf);
}
close(cfd);
return 0;
}
服务端结果:
客户端结果: