5.1 UDP通信流程
由于面向无连接通信,所以在收发数据时通过IP和端口
Server:
// 1. 创建套接字
int fd = socket(FA_INET, SOCK_DGRAM, 0);
// 2. 绑定IP和端口
bind();
// 3. 通信
// 接收数据:
recvfrom(); // 会保存client的IP和port
// 发送数据:
sendto();
// 4. 关闭套接字
close(fd);
Client:
// 1. 创建套接字
int fd = socket(AF_INET, SOCK_DGRAM, 0);
// 2. 通信
// 发送数据:
sendto();
// 接收数据:
recvfrom();
// 3. 关闭套接字
close(fd);
5.2 接受数据recvfrom()
#include <sys/types.h>
#include <sys/socket.h>
/*
* 函数功能:
* UDP通信接收数据
* 参数:
* sockfd:文件描述符
* buf:接受数据缓冲区
* len:buf的大小
* flags:0
* src_addr:另一端的地址信息(传出参数)
* addrlen:src_addr大小(出入传出参数)
* 返回值:
* 成功:读取的字节数
* 失败:-1
*/
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
5.3 发送数据sendto()
#include <sys/types.h>
#include <sys/socket.h>
/*
* 函数功能:
* UDP通信发送数据
* 参数:
* sockfd:文件描述符
* buf:需要发送的数据
* len:发送数据的大小
* flags:0
* dest_addr:另一端的地址信息
* addrlen:dest_addr大小
* 返回值:
* 成功:0
* 失败:-1
*/
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
5.4 Server代码实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
int main(int argc, const char *argv[])
{
// 1. 创建套接字
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket error:");
exit(-1);
}
// 2. 绑定
struct sockaddr_in serv;
serv.sin_family = AF_INET;
serv.sin_port = htons(9876);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(fd, (struct sockaddr*)&serv, sizeof(serv));
if(ret == -1)
{
perror("bind error:");
exit(-1);
}
// 3.通信
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
while(1)
{
char buf[1024] = { 0 };
int recvlen = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client_addr, &client_len);
if(recvlen == -1)
{
perror("recvfrom error:");
exit(-1);
}
char client_ip[64] = { 0 };
int client_port = ntohs(client_addr.sin_port);
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_ip , sizeof(client_ip));
printf("IP:%s:%d:%s\n",client_ip, client_port, buf);
// 发送数据
sendto(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client_addr, sizeof(client_addr));
}
close(fd);
return 0;
}
5.5 Client代码实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
int main(int argc, const char *argv[])
{
// 1. 创建套接字
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket error:");
exit(-1);
}
// 2. 通信
// 初始化服务器IP、Port
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(9876);
inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);
while(1)
{
char buf[1024] = { 0 };
fgets(buf, sizeof(buf), stdin);
// 发送数据
sendto(fd, buf, strlen(buf) + 1, 0, (const struct sockaddr*)&serv, sizeof(serv));
// 接收数据
recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
printf("recv buf:%s\n", buf);
}
return 0;
}