UDP sendto和recvfrom使用详解


udp

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

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

头文件

1 #include <sys/types.h>
2 #include <sys/socket.h>

函数原型

1 int sendto (int s, const void *buf, int len, unsigned int flags, const struct sockaddr *to, int tolen);
2  
3 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结构体

该结构体的定义如下:

01 /* Structure describing an Internet (IP) socket address. */
02 #define __SOCK_SIZE__   16      /* sizeof(struct sockaddr)  */
03 struct sockaddr_in {
04   sa_family_t       sin_family; /* Address family       */
05   __be16        sin_port;   /* Port number          */
06   struct in_addr    sin_addr;   /* Internet address     */
07  
08   /* Pad to size of `struct sockaddr'. */
09   unsigned char     __pad[__SOCK_SIZE__ - sizeof(short int) -
10             sizeof(unsigned short int) - sizeof(struct in_addr)];
11 };

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

1 #define AF_INET     2   /* Internet IP Protocol     */

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

1 /* Internet address. */
2 struct in_addr {
3     __be32  s_addr;
4 };

INADDR_ANY说明

INADDR_ANY,是个特殊IP地址 ,表示任务的IP地址,作为服务器端的时候经常要用到。对于它的解释,摘用下面一段英文(来自于:http://www.cs.cmu.edu/~srini/15-441/F01.full/www/assignments/P2/htmlsim_split/node18.html):

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:

01 #include <sys/types.h>
02 #include <sys/socket.h>
03 #include <netinet/in.h>
04 #include <arpa/inet.h>
05 #include <unistd.h>
06 #include <stdlib.h>
07 #include <string.h>
08 #include <stdio.h>
09  
10 #define UDP_TEST_PORT       50001
11  
12 int main(int argC, char* arg[])
13 {
14     struct sockaddr_in addr;
15     int sockfd, len = 0;   
16     int addr_len = sizeof(struct sockaddr_in);
17     char buffer[256];  
18  
19     /* 建立socket,注意必须是SOCK_DGRAM */
20     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
21         perror ("socket");
22         exit(1);
23     }
24  
25     /* 填写sockaddr_in 结构 */
26     bzero(&addr, sizeof(addr));
27     addr.sin_family = AF_INET;
28     addr.sin_port = htons(UDP_TEST_PORT);
29     addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据
30  
31     /* 绑定socket */
32     if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {
33         perror("connect");
34         exit(1);
35     }
36  
37     while(1) {
38         bzero(buffer, sizeof(buffer));
39         len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
40                        (struct sockaddr *)&addr ,&addr_len);
41         /* 显示client端的网络地址和收到的字符串消息 */
42         printf("Received a string from client %s, string is: %s\n",
43                 inet_ntoa(addr.sin_addr), buffer);
44         /* 将收到的字符串消息返回给client端 */
45         sendto(sockfd,buffer, len, 0, (struct sockaddr *)&addr, addr_len);
46     }
47  
48     return 0;
49 }
50  
51 // ----------------------------------------------------------------------------
52 // End of udp_server.c

UDP Client:

01 #include <sys/types.h>
02 #include <sys/socket.h>
03 #include <netinet/in.h>
04 #include <arpa/inet.h>
05 #include <unistd.h>
06 #include <stdlib.h>
07 #include <string.h>
08 #include <stdio.h>
09  
10 #define UDP_TEST_PORT       50001
11 #define UDP_SERVER_IP       "127.0.0.1"
12  
13 int main(int argC, char* arg[])
14 {
15     struct sockaddr_in addr;
16     int sockfd, len = 0;   
17     int addr_len = sizeof(struct sockaddr_in);     
18     char buffer[256];
19  
20     /* 建立socket,注意必须是SOCK_DGRAM */
21     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
22         perror("socket");
23         exit(1);
24     }
25  
26     /* 填写sockaddr_in*/
27     bzero(&addr, sizeof(addr));
28     addr.sin_family = AF_INET;
29     addr.sin_port = htons(UDP_TEST_PORT);
30     addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);
31  
32     while(1) {
33         bzero(buffer, sizeof(buffer));
34  
35         printf("Please enter a string to send to server: \n");
36  
37         /* 从标准输入设备取得字符串*/
38         len = read(STDIN_FILENO, buffer, sizeof(buffer));
39  
40         /* 将字符串传送给server端*/
41         sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);
42  
43         /* 接收server端返回的字符串*/
44         len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
45                        (struct sockaddr *)&addr, &addr_len);
46         printf("Receive from server: %s\n", buffer);
47     }
48  
49     return 0;
50 }
51  
52 // ----------------------------------------------------------------------------
53 // End of udp_client.c

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringOne Platform 2016回顾

我最近结束了在拉斯维加斯参加SpringOne Platform会议的总结。 这是我第一次参加SpringOne。 这是聆听演讲并与软件开发领域的一些顶级专家进行对话的一种体验。 如果您没有参加SpringOne&#xff0c;那么您肯定会想要阅读这篇文章。 我们将介绍这四个主题&#xff0c;以及如何…

欧姆龙cp1hum读保护解密步骤_欧姆龙PLC的NJ系列NJ产品功能介绍

欧姆龙PLC的NJ 系列NJ运动、逻辑和视觉集于一体欧姆龙PLC的NJ 系列NJ特点One Machine Control运动、逻辑和视觉集于一体将组成机械所需的各种控制设备汇集于一体&#xff0c;使用一个软件即可进行控制。 这就是Sysmac自动化平台的努力目标。 我们的新型机器自动化控制器NJ系列通…

关于CUDA和CuDNN配置的小问题

为了方便组员操作&#xff0c;简单写一下CUDA的配置啦。 首先你需要一台电脑&#xff0c;有NVDIA显卡的那种&#xff08;就那个煤气灶&#xff0c;你懂我意思吧&#xff09;&#xff0c;然后就继续往下走吧&#xff0c;如果没有的话可以找一下右上角的红叉了&#xff0c;这篇文…

PyMongo--非关系型数据库mongodb入门(一步一步 版)

PyMongo--非关系型数据库mongodb入门&#xff08;一步一步 版&#xff09; 本文主要内容&#xff1a; 1.简要介绍mongodb 2.Pymongo 3.mongo shell 4.我的mongodb入门之旅 1.简要介绍mongodb MongoDB是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的…

python画图颜色种类_Python可视化|matplotlib07-python colormap(颜色映射)(三)

本篇详细介绍matplotlib内置的颜色条Colormap使用。 本文将学到什么&#xff1f; 1、colormap名称 2、colormap可视化 3、colormap使用方法 4、参考资料 更好的阅读体验请戳&#xff1a; 1、colormap名称 colormap颜色通过matplotlib的cm模块调用&#xff0c;print(dir(cm))即可…

element table 组件内容换行方案

element table 组件内容换行方案 white-space的值&#xff1a; normal 默认。空白会被浏览器忽略。pre 空白会被浏览器保留。其行为方式类似 HTML 中的<pre> 标签。nowrap 文本不会换行&#xff0c;文本会在在同一行上继续&#xff0c;直到遇到 <br>标签为止。pre-…

UDP Socket编程 C/C++实现 (Windows Platform SDK)

挺无聊一小程序&#xff0c;俩SB一人说一句&#xff0c;据说聊天程序最好用UDP写。 Server&#xff1a; [csharp] view plaincopy #pragma comment (lib,"ws2_32.lib") #include <Winsock2.h> #include <stdio.h> void main() {…

关于Mongodb的全面总结,学习mongodb的人,可以从这里开始!

MongoDB的内部构造《MongoDB The Definitive Guide》 MongoDB的官方文档基本是how to do的介绍&#xff0c;而关于how it worked却少之又少&#xff0c;本人也刚买了《MongoDB TheDefinitive Guide》的影印版&#xff0c;还没来得及看&#xff0c;本文原作者将其书中一些关于M…

Spring Kafka生产者/消费者样本

我的目的是演示Spring Kafka如何为原始Kafka Producer和Consumer API提供一种易于使用且对具有Spring背景的人熟悉的抽象。 示例场景 示例场景是一个简单的场景&#xff0c;我有一个系统&#xff0c;该系统生成一条消息&#xff0c;另一个系统对其进行处理 使用Raw Kafka Pr…

homelede软路由设置方法_斐讯无线路由器怎么设置 斐讯无线路由器设置方法【详解】...

无线路由器的品类在不断增加&#xff0c;人们的生活也逐渐无法离开WIFI&#xff0c;各类无线路由器的设置方法大同小异&#xff0c;为了方便不为人知的小白更方便的设置无线路由器&#xff0c;这里详细介绍一下斐讯(phicomm)无线路由器怎么设置。配置前准备&#xff1a;A、请保…

Angular 个人深究(四)【生命周期钩子】

Angular 个人深究&#xff08;四&#xff09;【生命周期钩子】 定义&#xff1a; 每个组件都有一个被 Angular 管理的生命周期。 Angular 创建它&#xff0c;渲染它&#xff0c;创建并渲染它的子组件&#xff0c;在它被绑定的属性发生变化时检查它&#xff0c;并在它从 DOM 中被…

BITMAPINFO结构

BITMAPINFO结构定义了Windows设备无关位图&#xff08;DIB&#xff09;的度量和颜色信息。 一、BITMAPINFO结构形式&#xff1a; typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; 二、BITMAPINFO成员 bmi…

多媒体技术基础第四版林福宗pdf_意大利留学|没有绘画基础,还能考研艺术类专业吗?...

想学艺术专业&#xff0c;却没有绘画基础还能学艺术类专业么&#xff1f;意大利研究生的入学会简单一点 是典型的“宽进严出”想学艺术相关的专业&#xff0c;有2种看你是偏理论&#xff0c;还是偏实践。一起看一下&#xff01;偏实践方面纯艺类&#xff1a;油画、版画、雕塑、…

Spring Boot 1:Introduction

Spring Spring 在不断发展的过程中&#xff0c;边界不断扩张&#xff0c;需要的配置文件也越来越多&#xff0c;使用起来也越复杂&#xff0c;项目中也经常因为配置文件配置错误产生很多问题。即&#xff1a;Spring 逐渐变成了一个大而全的框架&#xff0c;背离它简洁开发的理念…

Pinely Round 3 (Div. 1 + Div. 2)

Pinely Round 3 (Div. 1 Div. 2) Pinely Round 3 (Div. 1 Div. 2) A. Distinct Buttons 题意&#xff1a;当前处于(0, 0)原点&#xff0c;给出若干个平面坐标轴上的点&#xff0c;是否可以仅选择三个方向便可以到达所有给出的点。 思路&#xff1a;到达单一坐标点最多需要…

在MFC,Win32程序中向控制台(Console)窗口输出调试信息

在MFC程序中输出调试信息的方法有两种&#xff0c;一种是使用TRACE宏&#xff0c;可以向Output窗口输出调试信息&#xff1b;另一种是用MessageBox&#xff0c;弹出消息框来输出调试信息&#xff0c;但会影响程序的运行。其实有一种方法可以更为方便的输出调试信息&#xff0c;…

C++程序内存泄漏都与哪些方面有关,该如何处理和避免

动态内存分配有几种: 一个是用了malloc/free, new/delete 第二个使用了第三方的库&#xff0c;库里面的API使用了第一种方法&#xff0c;他们需要你来释放空间&#xff0c;这个会在库的说明文档里有说明。 第三是程序递归&#xff0c;大量的程序递归和互相调用而不推出导致栈空…

unity vr是加一个摄像机就行吗_梦工厂和皮克斯员工创办的Baobab谈互动叙事:传统动画与VR动画的探索...

ACGN洞察访问三文娱网站3wyu.com查看产业必读文章Baobab工程师谈VR动画&#xff0c;以获得艾美奖和安妮奖的作品为例&#xff0c;介绍在跨媒体平台提升动画的质量、交互性和故事性。上个周末&#xff0c;Unite Shanghai 2019 在上海国际会议中心举行&#xff0c;来自世界各地的…

hbase regions_使用Regions ADF 11g进行Master Detail CRUD操作

hbase regions此示例演示了如何使用Regions在表之间创建Master Detail关系。 区域的主要目的是可重用性的概念。 使用区域和有限的任务流&#xff0c;我们可以将页面重用到许多其他页面中&#xff0c;以保持相同的功能并采用更简洁的方法 下载示例应用程序。 对于此示例&#…

(兔子繁殖问题)有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到三个月后每个月又生一对兔子,假如兔子都不死,问32个月过后的兔子总数为多少?...

网上关于这个问题有很多人说这个符合斐波那契数列&#xff0c;但是我个人在推算的时候发现并不是这样的&#xff0c;所以想自己解决这个问题 建立一个兔子类 属性有ID&#xff0c;age public class rabbit{ public  $id; public age; } 第1个月&#xff1a;(id1,age1)-------…