python recvfrom函数详解_UDP sendto和recvfrom使用详解「建议收藏」

python recvfrom函数详解_UDP sendto和recvfrom使用详解「建议收藏」在网络编程中,UDP运用非常广泛。很多网络协议是基于UDP来实现的,如SNMP等。大家常常用到的局域网文件传输软件飞鸽传书也是基于UDP实现的。本篇文章跟大家分享linux下UDP的使用和实现,主要介绍下sendto()和recvfrom()两个函数的使用,以及INADDR_ANY的说明,并在最后展示了一个经过自己测试可用的UDPServer和UDPClient的代码示例。头文件#inclu…

大家好,又见面了,我是你们的朋友全栈君。



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 Internet (IP) socket address. */

#define __SOCK_SIZE__16/* sizeof(struct sockaddr)*/

struct sockaddr_in {

sa_family_tsin_family;/* Address family*/

__be16sin_port;/* Port number*/

struct in_addrsin_addr;/* Internet address*/

/* Pad to size of `struct sockaddr’. */

unsigned char__pad[__SOCK_SIZE__ – sizeof(short int) –

sizeof(unsigned short int) – sizeof(struct in_addr)];

};

其中,sin_family指明地址族,一般使用AF_INET:

#define AF_INET2/* Internet IP Protocol */

sin_port:指明UDP端口;sin_addr指明IP地址:

/* Internet address. */

struct in_addr {

__be32s_addr;

};

INADDR_ANY说明

When you wrote your simple FTP server in project 1, you probably bound your listening socket to the special IP address INADDR_ANY. This allowed your program to work without knowing the IP address of the machine it was running on, or, in the case of a machine with multiple network interfaces, it allowed your server to receive packets destined to any of the interfaces. In reality, the semantics of INADDR_ANY are more complex and involved.

In the simulator, INADDR_ANY has the following semantics: When receiving, a socket bound to this address receives packets from all interfaces. For example, suppose that a host has interfaces 0, 1 and 2. If a UDP socket on this host is bound using INADDR_ANY and udp port 8000, then the socket will receive all packets for port 8000 that arrive on interfaces 0, 1, or 2. If a second socket attempts to Bind to port 8000 on interface 1, the Bind will fail since the first socket already “owns” that port/interface.

When sending, a socket bound with INADDR_ANY binds to the default IP address, which is that of the lowest-numbered interface.

大概的意思就是,作为接收端,当你调用bind()函数绑定IP时使用INADDR_ANY,表明接收来自任意IP、任意网卡的发给指定端口的数据。作为发送端,当用调用bind()函数绑定IP时使用INADDR_ANY,表明使用网卡号最低的网卡进行发送数据,也就是UDP数据广播。

关于UDP数据报

UDP都是以数据报的形式进行发送和接收的,而TCP是以数据流的形式进行发送和接收的。数据报和数据流,这两者要区分开来。

UDP Server和Client源码实例

UDP Server:

#include

#include

#include

#include

#include

#include

#include

#include

#defineUDP_TEST_PORT50001

int main(int argC, char* arg[])

{

struct sockaddr_in addr;

int sockfd, len = 0;

int addr_len = sizeof(struct sockaddr_in);

char buffer[256];

/* 建立socket,注意必须是SOCK_DGRAM */

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

perror (“socket”);

exit(1);

}

/* 填写sockaddr_in 结构 */

bzero(&addr, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(UDP_TEST_PORT);

addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据

/* 绑定socket */

if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {

perror(“connect”);

exit(1);

}

while(1) {

bzero(buffer, sizeof(buffer));

len = recvfrom(sockfd, buffer, sizeof(buffer), 0,

(struct sockaddr *)&addr ,&addr_len);

/* 显示client端的网络地址和收到的字符串消息 */

printf(“Received a string from client %s, string is: %s\n”,

inet_ntoa(addr.sin_addr), buffer);

/* 将收到的字符串消息返回给client端 */

sendto(sockfd,buffer, len, 0, (struct sockaddr *)&addr, addr_len);

}

return 0;

}

// —————————————————————————-

// End of udp_server.c

UDP Client:

#include

#include

#include

#include

#include

#include

#include

#include

#defineUDP_TEST_PORT50001

#define UDP_SERVER_IP “127.0.0.1”

int main(int argC, char* arg[])

{

struct sockaddr_in addr;

int sockfd, len = 0;

int addr_len = sizeof(struct sockaddr_in);

char buffer[256];

/* 建立socket,注意必须是SOCK_DGRAM */

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

perror(“socket”);

exit(1);

}

/* 填写sockaddr_in*/

bzero(&addr, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(UDP_TEST_PORT);

addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);

while(1) {

bzero(buffer, sizeof(buffer));

printf(“Please enter a string to send to server: \n”);

/* 从标准输入设备取得字符串*/

len = read(STDIN_FILENO, buffer, sizeof(buffer));

/* 将字符串传送给server端*/

sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);

/* 接收server端返回的字符串*/

len = recvfrom(sockfd, buffer, sizeof(buffer), 0,

(struct sockaddr *)&addr, &addr_len);

printf(“Receive from server: %s\n”, buffer);

}

return 0;

}

// —————————————————————————-

// End of udp_client.c

上述代码是经过验证可用的。

» 文章出处:

reille博客—http://velep.com

, 如果没有特别声明,文章均为reille博客原创作品

» 郑重声明:

原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)

分享到:

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163421.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • oracle字符串自身去重,oracle拼接字符串函数(去重和不去重)「建议收藏」

    oracle字符串自身去重,oracle拼接字符串函数(去重和不去重)「建议收藏」oracle拼接字符串函数(去重和不去重)1.不去重FUNCTIONf_linkFunctionf_linkCREATEORREPLACEFUNCTIONf_link(p_strVARCHAR2)RETURNVARCHAR2PARALLEL_ENABLEAGGREGATEUSINGt_link;Typet_linkCREATEORREPLACETYPET_LINK…

    2022年9月20日
    4
  • ubuntu更新源

    ubuntu更新源1.备份原始源文件source.list打开终端,输入:sudocp/etc/apt/sources.list/etc/apt/sources.list.bak2.修改源文件1.继续输入:

    2022年7月4日
    20
  • T-SQL教程_sql server 2008使用

    T-SQL教程_sql server 2008使用文章目录T-SQL基础技术基本语法格式代码准备:(可以按照我的实例自行建立数据库)1、投影查询a、投影指定的列b、投影全部列c、修改查询结果的列标题d、去掉重复行2、选择查询a.表达式比较b.范围比较c.模式匹配d.空值使用代码示例:3、连接查询a.连接谓词b.以JOIN关键字指定的连接(1)内连接(2)外连接4、统计计算5、排序查询6、子查询T-SQL基础技术T-SQL语言中最重要的部分是它…

    2022年8月18日
    7
  • 检查网站有没有被挂马_网站在线挂马检测工具

    检查网站有没有被挂马_网站在线挂马检测工具首先,我们来看看网站被挂马的危害性。网站被挂马后,一方面是系统资源,流量带宽资源的巨大损失,另一方面也成为了传播网页木马的“傀儡帮凶”,严重影响到网站的公众信誉度。很多网页木马都是利益驱动,偷盗各类帐号密码,如电子银行帐户和密码、游戏帐号和密码、邮箱帐户和密码、qq/MSN帐号和密码等;另外,使得客户端被安装恶意插件,强迫浏览黑客指定的网站,或者被利用攻击某个站点等。  我们知道了网站被挂马

    2022年9月27日
    3
  • 如何评估词向量?「建议收藏」

    如何评估词向量?「建议收藏」如何评估词向量?目前词向量的评估一般分为两大类:extrinsic和intrinsicevaluation即内部评估和外部评估。内部评估内部评估直接衡量单词之间的句法和语义关系。这些任务通常涉及一组预先选择的查询术语和语义相关的目标词汇,我们将其称为queryinventory。similarity相关性度量当前绝大部分工作(比如以各种方式改进wordembedding)都…

    2022年5月29日
    55
  • python向上取整和向下取整(python除法向下取整)

    广告关闭腾讯云11.11云上盛惠,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!importmathf=11.2printmath.ceil(f)#向上取整printmath.floor(f)#向下取整printround(f)#四舍五入#这三个函数的返回结果都是浮点型…python中向上取整可以用ceil函数,ceil函数是在math模…

    2022年4月16日
    235

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号