python recvfrom函数详解_UDP sendto和recvfrom使用详解



在网络编程中,UDP运用非常广泛。很多网络协议是基于UDP来实现的,如SNMP等。大家常常用到的局域网文件传输软件飞鸽传书也是基于UDP实现的。

本篇文章跟大家分享linux下UDP的使用和实现,主要介绍下sendto()和recvfrom()两个函数的使用,以及INADDR_ANY的说明,并在最后展示了一个经过自己测试可用的UDP Server和UDP Client的代码示例。

头文件

#include

#include

函数原型

int sendto (int s, const void *buf, int len, unsigned int flags, const struct sockaddr *to, int tolen);

int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);

函数说明

sendto(),是把UDP数据报发给指定地址;recvfrom()是从指定地址接收UDP数据报。

参数说明

\s:              socket描述符。

\buf:         UDP数据报缓存地址。

\len:          UDP数据报长度。

\flags:       该参数一般为0。

\to:            sendto()函数参数,struct sockaddr_in类型,指明UDP数据发往哪里报。

\tolen:      对方地址长度,一般为:sizeof(struct sockaddr_in)。

\fromlen:recvfrom()函数参数,struct sockaddr_in类型,指明从哪里接收UDP数据报。

函数返回值

对于sendto()函数,成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中。

对于recvfrom()函数,成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。

struct sockaddr_in结构体

该结构体的定义如下:

/* Structure describing an

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`recvfrom` 函数用于接收一个来自指定套接字的数据报,并将发送方的地址和端口号存储在指定的缓冲区中。 函数原型如下: ```c #include <sys/socket.h> 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。 注意事项: - 如果套接字是非阻塞的,则 `recvfrom` 函数可能会返回 -1 并设置 `errno` 为 `EAGAIN` 或 `EWOULDBLOCK`。 - 如果接收缓冲区中的数据长度大于 `len`,则数据将被截断。 - `src_addr` 和 `addrlen` 参数可以设置为 `NULL`,表示不关心发送方地址信息。 示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int sockfd; struct sockaddr_in server_addr, client_addr; socklen_t client_addrlen = sizeof(client_addr); char buffer[BUFFER_SIZE]; // 创建套接字 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket creation failed"); exit(EXIT_FAILURE); } // 绑定地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); if (bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 接收数据 ssize_t num_bytes; while (1) { memset(buffer, 0, BUFFER_SIZE); num_bytes = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &client_addrlen); if (num_bytes < 0) { perror("recvfrom failed"); exit(EXIT_FAILURE); } printf("Received message from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); printf("Data: %s\n", buffer); } close(sockfd); return 0; } ``` 该示例代码创建一个 UDP 服务器,不断接收发送方发送的数据,并输出发送方的地址信息和数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值