当前位置: 代码网 > 服务器>服务器>Linux > Linux UDP通信中sendto和recvfrom函数怎么用

Linux UDP通信中sendto和recvfrom函数怎么用

2026年09月20日 Linux 我要评论
一、基础概述sendto 与 recvfrom 是 linux udp 通信专属收发函数。因为 udp 是无连接协议,通信双方没有固定对端,每次收发数据都必须手动指定对方 ip 和端口,因此 udp

一、基础概述

sendtorecvfrom 是 linux udp 通信专属收发函数。因为 udp 是无连接协议,通信双方没有固定对端,每次收发数据都必须手动指定对方 ip 和端口,因此 udp 只能使用这两个函数完成数据传输。

头文件:

#include <sys/socket.h>

二、sendto 函数详解

1. 函数原型

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);

2. 参数解析

参数

详细说明

sockfd

udp 套接字文件描述符,由 socket(af_inet, sock_dgram, 0) 创建

buf

待发送的数据缓冲区

len

需要发送的数据有效长度

flags

标志位,常规开发固定填 0

dest_addr

目标地址结构体,存放对方 ip、端口,需要强转为通用地址类型

addrlen

地址结构体大小,填写 sizeof(struct sockaddr_in)

3. 返回值

  • 大于 0:成功发送的字节数,udp 一次发送一整个数据报,无粘包、无半包

  • -1:发送失败,errno 保存错误信息

4. 代码示例(仅使用基础字节序函数)

struct sockaddr_in dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr));

dest_addr.sin_family = af_inet;
dest_addr.sin_port = htons(8888);         // 主机端口转网络大端
inet_aton("127.0.0.1", &dest_addr.sin_addr); // 字符串ip转网络大端

char msg[] = "hello udp";
ssize_t ret = sendto(sockfd, msg, strlen(msg), 0,
                     (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if(ret == -1)
{
    perror("sendto failed");
}

5. 函数特性

  • 专门用于 udp 无连接通信,每次发送必须指定目标地址

  • 面向数据报,一次函数调用对应一条完整 udp 报文

  • 不存在 tcp 的粘包、半包问题

  • tcp 套接字可以调用但无意义,地址参数会被内核忽略,工程中不用

三、recvfrom 函数详解

1. 函数原型

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);

2. 参数解析

参数

详细说明

sockfd

udp 套接字,一般已经完成 bind 端口绑定

buf

数据接收缓冲区

len

缓冲区最大接收长度

flags

标志位,常规填 0

src_addr

输出参数,函数自动填入发送方的 ip、端口信息

addrlen

输入输出参数:调用前赋值结构体大小,调用后更新为真实地址长度

3. 返回值

  • 大于 0:成功接收的数据字节数

  • 等于 0:接收到空 udp 报文

  • -1:接收失败或阻塞出错

4. 代码示例(搭配基础字节序打印)

char buf[1024] = {0};
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);

ssize_t n = recvfrom(sockfd, buf, sizeof(buf)-1, 0,
                     (struct sockaddr *)&client_addr, &addr_len);
if(n > 0)
{
    buf[n] = '\0';
    // 网络字节序转主机字节序打印
    printf("收到消息:%s,来自 %s:%d\n",
           buf,
           inet_ntoa(client_addr.sin_addr),
           ntohs(client_addr.sin_port));
}

5. 函数特性

  • udp 服务端专属接收函数,可以自动获取客户端地址,用于原路回复数据

  • 默认阻塞,没有数据时程序挂起等待

  • 接收缓冲区小于报文长度时,数据会静默截断丢失,无报错

  • tcp 场景调用无意义,工程中不使用

四、常用 flags 标志

标志

作用

0

默认常规收发

msg_peek

偷看数据,数据不删除,下次仍可接收

msg_nosignal

不产生 sigpipe 信号,避免程序崩溃退出

五、核心易错点总结

  • recvfrom 的 addrlen 必须传 socklen_t 变量地址,不能传常量、不能传 sizeof 地址

  • udp 数据没有 \0,接收后必须手动补结束符,否则乱码

  • 端口赋值用 htons,端口打印用 ntohs

  • ip 赋值用 inet_aton,ip 打印用 inet_ntoa

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com