Skip to main content

moregeek program

#盲盒+码#【ffh】学习设备开发之hi3861-udp-广播_鸿蒙社区的博客-多极客编程

(目录)
【本文正在参加「盲盒」+码有奖征文活动】:https://ost.51cto.com/posts/19288


一、前言


上文,【FFH】学习设备开发之Hi3861-TCPclient-开关灯留下了的疑惑:
在net_demo.h文件里,testFun是什么?它是怎么选择客户端还是服务端再跳转到tcp_client_test.c文件执行TcpClientTest()函数的呢?
image.png
搞不懂别人高深的代码,于是后面就仿照官方代码,自己写了一份简单的代码,并且学习另一种传输协议UDP。


二、UDP简介


1.定义


用户数据报协议(UDP):UDP(用户数据报协议)是一个简单的面向数据报的传输层协议。提供的是==非面向连接的、不可靠的数据流传输==。UDP不提供可靠性,也不提供报文到达确认、排序以及流量控制等功能。==它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地==。因此报文可能会丢失、重复以及乱序等。但由于UDP在传输数据报前==不用在客户和服务器之间建立一个连接==,且没有超时重发等机制,故而==传输速度很快==。


2.复习一下TCP


“面向连接的TCP”就是在正式通信前必须要与对方建立起连接。TCP协议是一种可靠的、一对一的、面向有连接的通信协议。


3.UDP/TCP区别


TCP和UDP最大的区别就是:TCP是==面向连接==的,UDP是==无连接==的。TCP协议和UDP协议各有所长、各有所短,适用于不同要求的通信环境。TCP协议和UDP协议之间的差别如下表所示。
在实际的使用中,TCP主要应用于文件传输==精确性==相对要求较高且不是很紧急的情景,比如电子邮件、远程登录等。有时在这些应用场景下即使丢失一两个字节也会造成不可挽回的错误,所以这些场景中一般都使用TCP传输协议。由于UDP可以==提高传输效率==,所以UDP被广泛应用于数据量大且精确性要求不高的数据传输,比如我们平常在网站上观看视频或者听音乐的时候应用的基本上都是UDP传输协议。
image.png
开发流程图:
UDP👇
9c6006b76797998dc0c6cf08e8c6ab6.png
TCP👇
image.png


三、代码


1.把连接WiFi的代码搬过来


image.png
在net_params.h文件里配置WiFi


#ifndef PARAM_HOTSPOT_SSID
#define PARAM_HOTSPOT_SSID "Fsr" // your AP SSID
#endif

#ifndef PARAM_HOTSPOT_PSK
#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK
#endif

连接WiFi


//连接wifi
WifiDeviceConfig config = {0};

// 准备AP的配置参数
strcpy(config.ssid, PARAM_HOTSPOT_SSID);
strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
config.securityType = PARAM_HOTSPOT_TYPE;

osDelay(10);
//开始连接
int netId = ConnectToHotspot(&config);


==记得在udp文件夹里的BUILD.gn编译WiFi的.c文件==
image.png


2.简单的UDP


// 1.创建udp
int sock_fd;
int ret;
sock_fd = socket(AF_INET, SOCK_DGRAM, 0); //SOCK_DGRAM:UDP类型的socket
if (sock_fd < 0)
{
perror("sock_fd create error\r\n");
return;
}

// 2.配置地址
struct sockaddr_in send_addr;
socklen_t send_addr_len = sizeof(send_addr);
//内存初始化
memset((void *)&send_addr, 0, send_addr_len);
send_addr.sin_family = AF_INET;

send_addr.sin_addr.s_addr = inet_addr("192.168.11.41"); // 是将一个点分十进制的IP转换成一个长整数型数(u_long类型)
send_addr.sin_port = htons(1234); // 端口号,从主机字节序转为网络字节序
// 3.配置发送消息
char *msg = "hello world";
while (1)
{
//4.发送
// UDP socket 是 “无连接的” ,因此每次发送都必须先指定目标主机和端口,主机可以是多播地址
ret = sendto(sock_fd, msg, strlen(msg), 0, (struct sockaddr *)&send_addr, send_addr_len);
printf("send UDP message {%s}done!\r\n", msg);
usleep(1 * 1000 * 1000);

// 5.接收
struct sockaddr_in fromAddr = {0};
socklen_t fromLen = sizeof(fromAddr);
// UDP socket 是 “无连接的” ,因此每次接收时前并不知道消息来自何处,通过 fromAddr 参数可以得到发送方的信息(主机、端口号)
ret = recvfrom(sock_fd, &response, sizeof(response), 0, (struct sockaddr *)&fromAddr, &fromLen);
if (ret <= 0)
{
printf("recvfrom failed or abort, %ld!\r\n", ret);
}
response[ret] = '\0';
printf("recv UDP message {%s} %ld done!\r\n", response, ret);
printf("peer info: ipaddr = %s, port = %d\r\n", inet_ntoa(fromAddr.sin_addr), ntohs(fromAddr.sin_port)); //将网络地址转换成“.”点隔的字符串格式。将一个16位数由网络字节顺序转换为主机字节顺序
}

代码中主要的函数与TCP一样都是用socket,已在上文,【FFH】学习设备开发之Hi3861-TCPclient-开关灯解释。
两者开发过程的区别:
创建socket的类型type=SOCK_STREAM(TCP)/SOCK_DGRAM(UDP)


int sockfd = socket(AF_INET, type, 0);

TCP需要多一步与主机连接,而UDP不需要
image.png


3.代码运行结果


netcat,-u代表主机使用UDP协议传输,-l 开启监听,-p指定端口
image.png


四、UDP广播


因为UDP是无连接的,并且一对多发送消息,自然而然就具有广播消息的功能。
下面给出主要代码👇


// 1.创建udp
int sock_fd;
int ret;
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0)
{
perror("sock_fd create error\r\n");
return;
}

// 2.设置广播模式
int yes = 1;
ret = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
// SOL_SOCKET表示给当前的socketfd,赋予SO_BROADCAST广播权限
if (ret == -1)
{
perror("setsockopt error\r\n");
return;
}

// 3.配置广播地址
struct sockaddr_in broadcast_addr;
socklen_t broadcast_addr_len = sizeof(broadcast_addr);
//初始化地址内存
memset((void *)&broadcast_addr, 0, broadcast_addr_len);
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); //INADDR_BROADCAST:要发送给所有主机的地址
broadcast_addr.sin_port = htons(1234);

char *msg = "hello ";
while (1)
{
ret = sendto(sock_fd, msg, strlen(msg), 0, (struct sockaddr *)&broadcast_addr, broadcast_addr_len);

usleep(1 * 1000 * 1000);
}

设置广播模式的函数:


setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes)); 

int setsockopt( int socket, int level, int option_name,const void *option_value, size_t ,ption_len);

第一个参数socket是套接字描述符。
第二个参数level是被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为 SOL_SOCKET。
第三个参数option_name指定准备设置的选项,option_name可以有哪些取值,这取决于level。当level取SOL_SOCKET时,option_name可取
SO_DEBUG,打开或关闭调试信息。
SO_REUSEADDR,打开或关闭地址复用功能。 当option_value不等于0时,打开,否则,关闭。
SO_DONTROUTE,打开或关闭路由查找功能。 当option_value不等于0时,打开,否则,关闭。
==SO_BROADCAST,允许或禁止发送广播数据。 当option_value不等于0时,允许,否则,禁止。==
不需要确定发给哪个特定的主机,所以要设置广播的地址为所有。


 broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); //INADDR_BROADCAST:要发送给所有主机的地址

本文作者:Z·y


想了解更多关于开源的内容,请访问:​


​51CTO 开源基础软件社区​


​https://ost.51cto.com/#bkwz​


©著作权归作者所有:来自51CTO博客作者开源基础软件社区官方的原创作品,请联系作者获取转载授权,否则将追究法律责任

c语言动态内存管理_158shi的博客-多极客编程

在学习和使用C语言的过程中经常要编写管理内存的程序,往往提心吊胆。若是不想踩雷,唯一的办法就是深入理解内存管理,发现所有的陷阱并排除他们。内存的使用方式内存主要有三种分配方式:(1)在栈(Stack)上创建。可以在栈区创建数个局部变量或者局部数组。函数结束执行时这些内存被自动释放。(2)从静态区(Static)分配。在静态区创建全局变量,static修饰的变量和常量字符串都在静态区存储。这些内存在

spring cloud config 配置_spring认证的博客-多极客编程

3.1.5Spring Cloud Config 为分布式系统中的外部化配置提供服务器端和客户端支持。使用配置服务器,您可以在一个中心位置管理所有环境中应用程序的外部属性。 客户端和服务器上的概念与 Springandabstractions 的映射相同,因此它们非常适合 Spring 应用程序,但可以与以任何语言运行的任何应用程序一起使用。 当应用程序通过部署管道从开发到测试再到生产时,可以管理

spring cloud connectors 连接器_spring认证的博客-多极客编程

介绍Spring Cloud Connector 为在云平台上运行的基于 JVM 的应用程序提供了一个简单的抽象,以便在运行时发现绑定服务和部署信息,并支持将发现的服务注册为 Spring bean。它基于插件模型,因此相同的编译应用程序可以部署在本地或多个云平台中的任何一个上,并且它支持通过Java服务提供程序接口(SPI)自定义服务定义。连接器项目为发现 Heroku 和 Cloud Foun

spring boot中添加thymeleaf模板_mb62c3ac8538829的博客-多极客编程

Spring Boot中添加Thymeleaf模板前面我们讲解了Spring Boot项目的创建、Spring Boot结构信息,自动配置功能等,那么Springboot创建出来,我们最终是要做web开发的,所以我们这章讲解如何用SpringBoot做web开发。一. Web开发方式Spring boot提供了一套完整的web开发流程,从前端到后台,再到数据库,定时任务,消息队列等都可以支持.一般

#yyds干货盘点# leetcode程序员面试金典:回文排列_灰太狼_cxh的博客-多极客编程

题目:给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。回文串不一定是字典当中的单词。 示例1:输入:"tactcoa"输出:true(排列有"tacocat"、"atcocta",等等) 代码实现:class Solution { public boolean canPermutePalindrome(Strin

#yyds干货盘点# 动态规划专题:数位染色_风的博客-多极客编程

1.简述:描述小红拿到了一个正整数  。她可以将其中一些数位染成红色。然后她想让所有染红的数位数字之和等于没染色的数位数字之和。她不知道能不能达成目标。你能告诉她吗?输入描述:一个正整数  ,输出描述:如果小红能按要求完成染色,输出"Yes"。否则输出"No"。示例1输入:1234567输出:Yes说明:将3、4、7染成红色即可,这样3+4+7=1+2+5+6示例2输入:23输出:No说明:显然无

#盲盒+码#【ffh】学习设备开发之hi3861-tcpclient-开关灯_鸿蒙社区的博客-多极客编程

(目录) 【本文正在参加「盲盒」+码有奖征文活动】:https://ost.51cto.com/posts/19288 一、前言 学习OpenHarmony南向设备开发中的网络通信,它可以将底层开发板获得的数据传输到上层的服务器,服务器亦可通过网络通信控制底层开发板。 二、TCP简介 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字

openharmony 3.2 beta多媒体系列——音视频播放框架_鸿蒙社区的博客-多极客编程

作者:巴延兴 一、简介 媒体子系统为开发者提供一套接口,方便开发者使用系统的媒体资源,主要包含音视频开发、相机开发、流媒体开发等模块。每个模块都提供给上层应用对应的接口,本文会对音视频开发中的音视频播放框架做一个详细的介绍。 二、目录 foundation/multimedia/media_standard ├── frameworks #框架代码

harmonyos arkts 本地库&三方库的用法_鸿蒙社区的博客-多极客编程

项目介绍 项目内容: 自定义基础组件和容器组件、依赖库概念、本地依赖库的创建和引用、三方库的引用。 工具版本: DevEco Studio 3.1 Canary1 SDK版本: 3.2.1.4(API Version 9 Canary1)(Stage模型) 本项目基于HarmonyOS的ArkUI框架TS扩展的声明式开发范式,关于语法和概念直接看官网官方文档地址:基于TS扩展的声明式开发范式, 效

#盲盒+码##跟着小白一起学鸿蒙# [番外三]一起学做tetris(上)_鸿蒙社区的博客-多极客编程

作者:王石 简介 小时候有个游戏叫俄罗斯方块,大人小孩都喜欢玩,我们就一起看看如何能用OpenHarmony学习做个Tetris。 开发 1. HAP应用建立 《#跟着小白一起学鸿蒙#[六]如何编写一个hap应用》里我们介绍了简单的Hap应用的开发以及基础控件的介绍,这里我们就不赘述Hap项目的建立过程,以下就是基础的Hap的page文件:index.ets build() { R

#盲盒+码##深入浅出学习ets#(十九)tcp聊天室_鸿蒙社区的博客-多极客编程

【本文正在参加「盲盒」+码有奖征文活动】https://ost.51cto.com/posts/19288 本项目Gitee仓地址:深入浅出eTs学习: 带大家深入浅出学习eTs (gitee.com) 一、需求分析 本章节我们来实现一个TCP聊天的功能 连接指定IP和端口 显示接收的内容 具有发送的功能 二、控件介绍 (1)Socket连接 场景介绍 应用通过Socket进行数据传输,支持

#盲盒+码# #跟着小白一起学鸿蒙# [番外]一起学做tetris(下)_鸿蒙社区的博客-多极客编程

#跟着小白一起学鸿蒙# [番外]一起学做Tetris(下) 作者:王石 简介 接着《#跟着小白一起学鸿蒙# [番外]一起学做Tetris(上)》我们完善了页面,增加了左右按键和之前方块显示,方块消除。 开发 1. 按键增加 之前我们布局一直是只有个Canvas控件,现在我们需要设置高度后增加一个Row的布局,并增加两个Button控件,以下就是基础的Hap的page文件:index.ets