Flutter局域网广播(UDP通信)与TCP通信

前言

现在有一个需求,手机和ESP32通过WIFI进行通信。流程如下:

  • 手机创建TCP服务器
  • 手机向192.168.0.255的1002端口广播自己的ip地址以及TCP服务器的端口号
  • ESP32监听到1002的广播内容后,连接手机的TCP服务器。
  • 最后就是ESP32硬件和TCP服务器进行数据收发

因此我们要了解Flutter如何使用UDP进行广播、如何创建TCP服务器以及通过TCP进行通信

验证工具

假如我们代码写好了,和硬件直接调试发现出现了错误,我们就无法定位是Flutter的代码问题还是硬件的问题。因此需要一个验证工具来验证是哪方面出现了问题

这里我们使用验证工具是“山外多功能调试助手”

模拟TCP服务器

  • 打开山外多功能调试助手
  • 点击网络调试助手,再点击TCP服务器

  • 输入端口号点击监听,硬件根据ip地址和端口号进行连接,在消息区我们可以看到是否有设备连接

  • ESP32能够连接这个软件说明错误问题在手机程序中

模拟TCP客户端

  • 前端创建好了TCP服务端后,可以通过这个软件进行连接测试
  • 打开“山外多功能调试助手”,点击网络调试助手,点击TCP客户端
  • 输入服务器IP地址以及端口号,点击连接后查看消息是否连接成功

如果能够连接成功则说明我们的TCP服务器创建成功

模拟UDP广播

  • 点击网络调试助手——>点击UDP,输入广播的端口号后点击连接
  • 手机程序发送一个广播,在消息区可以看到广播的内容

创建TCP服务器

要在Flutter中创建TCP服务器,您可以使用dart:io库中的ServerSocket类。

下面代码使用ServerSocket.bind()方法绑定服务器的地址和端口。然后,我们使用server.listen()来监听来自客户端的连接。当客户端连接到服务器时,我们打印连接信息并向客户端发送欢迎消息。

接下来,我们通过socket.listen()来监听客户端发送的数据。当接收到数据时,我们打印收到的消息,并向客户端发送回复消息。如果在接收数据时出现错误或客户端断开连接,我们关闭与客户端的连接。

startServer() async {try {_serverSocket?.close();_serverSocket = await ServerSocket.bind(InternetAddress.anyIPv4, 5556);print( '服务器已启动,地址:${_serverSocket?.address.address}:${_serverSocket?.port}');_serverSocket?.listen(serverOnReceive);} catch (e, stackTrace) {print('e---------:$e');}
}
serverOnReceive(Socket socket) {_socket = socket;print('客户端已连接: ${socket.remoteAddress}:${socket.remotePort}');socket.writeln('欢迎连接到服务器'); // 向客户端发送欢迎消息_socket?.listen((data) {print('接收到客户端消息: $data');socket.writeln('服务器收到消息: $data'); // 回复客户端收到的消息},onError: (error) {print('接收数据时出现错误: $error');socket.close(); // 关闭与客户端的连接},onDone: () {print('客户端已断开连接');socket.close(); // 关闭与客户端的连接},);
}

局域网广播

权限设置

android

在Flutter中发送广播消息所涉及的权限取决于您的目标平台和网络环境。以下是一些常见的权限,您可能需要在Flutter应用程序中配置以发送广播消息:

对于Android平台:

  • android.permission.INTERNET:用于访问互联网。
  • android.permission.ACCESS_NETWORK_STATE:用于访问网络状态信息。
  • android.permission.ACCESS_WIFI_STATE:用于访问Wi-Fi状态信息。
  • android.permission.CHANGE_WIFI_MULTICAST_STATE:用于更改Wi-Fi多播状态。
对于ios平台
  • NSLocalNetworkUsageDescription:描述应用程序使用本地网络的目的,添加该键值对到应用程序的Info.plist文件中。

示例Info.plist文件中的键值对配置部分:

<key>NSLocalNetworkUsageDescription</key><string>需要使用本地网络以发送广播消息。</string>
具体代码

在Flutter中,可以使用dart:io库中的RawDatagramSocket类来发送广播消息。以下是一个简单的示例代码,演示如何在Flutter中发送广播消息:

void sendBroadcastMessage() {String message = 'BB192.168.0.174:5556';print(utf8.encode(message));RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).then((RawDatagramSocket socket) {rawDatagramSocket = socket;var broadcastAddr = InternetAddress('255.255.255.255');var port = 1002; // 广播目标端口socket.broadcastEnabled = true;socket.send(utf8.encode(message), broadcastAddr, port);socket.close();}).catchError((error) {print('发送广播消息时出现错误: $error');});
}

全部代码

import 'dart:convert';
import 'dart:io';import 'package:flutter/material.dart';ServerSocket? _serverSocket;
Socket? _socket;
RawDatagramSocket? rawDatagramSocket;class TCPServe extends StatefulWidget {const TCPServe({super.key});@overrideState<TCPServe> createState() => _TCPServeState();
}class _TCPServeState extends State<TCPServe> {startServer() async {print("InternetAddress.anyIPv4:${InternetAddress.loopbackIPv4}");try {_serverSocket?.close();// _serverSocket = await ServerSocket.bind("localhost", 1234);_serverSocket = await ServerSocket.bind(InternetAddress.anyIPv4, 5556);print('服务器已启动,地址: ${_serverSocket?.address.address}:${_serverSocket?.port}');_serverSocket?.listen(serverOnReceive);} catch (e, stackTrace) {print('e---------:$e');}}serverOnReceive(Socket socket) {_socket = socket;print('客户端已连接: ${socket.remoteAddress}:${socket.remotePort}');socket.writeln('欢迎连接到服务器'); // 向客户端发送欢迎消息_socket?.listen((data) {print('接收到客户端消息: $data');socket.writeln('服务器收到消息: $data'); // 回复客户端收到的消息},onError: (error) {print('接收数据时出现错误: $error');socket.close(); // 关闭与客户端的连接},onDone: () {print('客户端已断开连接');socket.close(); // 关闭与客户端的连接},);}clean() async {await _socket?.close();print("_socket关闭");await _serverSocket?.close();print("_serverSocket关闭");}void sendBroadcastMessage() {String message = 'BB192.168.0.174:5556';print(utf8.encode(message));RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).then((RawDatagramSocket socket) {rawDatagramSocket = socket;var broadcastAddr = InternetAddress('255.255.255.255');var port = 1002; // 广播目标端口socket.broadcastEnabled = true;socket.send(utf8.encode(message), broadcastAddr, port);socket.close();}).catchError((error) {print('发送广播消息时出现错误: $error');});}cleanRawDatagramSocket() {rawDatagramSocket?.close();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("TCP服务端测试")),body: Center(child: Column(children: [TextButton(onPressed: startServer,child: const Text("创建服务"),),TextButton(onPressed: clean,child: const Text("关闭服务"),),TextButton(onPressed: () {_socket?.writeln('REVERSE_LED');},child: const Text("发送REVERSE_LED"),),TextButton(onPressed: sendBroadcastMessage,child: const Text("开始广播"),),TextButton(onPressed: cleanRawDatagramSocket,child: const Text("关闭广播"),),],),),);}
}

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

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

相关文章

双击热备 Electron网页客户端

安装流程&#xff1a; 1.下载node.js安装包进行安装 2.点击Next; 3.勾选&#xff0c;点击Next; 4.选择安装目录 5.选择Online 模式 6.下一步执行安装 。 7.运行cmd,执行命令 path 和 node --version&#xff0c;查看配置路径和版本 8.Goland安装插件node.js 9.配置运行…

深入理解Go语言中的并发封闭与for-select循环模式

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在现代编程中,并发已经成为提高程序性能和响应能力的关键手段。然而,在并发环境下,如何安全地访问和操作共享数据却是一大挑战。本文将深入探讨Go语言中的**封闭(confinement)**技术,以及常见的for-select循…

操作系统:进程间通信方式详解(下:消息队列、信号量、共享内存、套接字)

每日一问&#xff1a;操作系统&#xff1a;进程间通信方式详解&#xff08;下&#xff1a;消息队列、信号量、共享内存、套接字&#xff09; 进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是操作系统中实现不同进程之间数据交换和协作的关键机…

【有啥问啥】深度剖析:大模型AI时代下的推理路径创新应用方法论

深度剖析&#xff1a;大模型AI时代下的推理路径创新应用方法论 随着大规模预训练模型&#xff08;Large Pretrained Models, LPMs&#xff09;和生成式人工智能的迅速发展&#xff0c;AI 在多领域的推理能力大幅提升&#xff0c;尤其是在自然语言处理、计算机视觉和自动决策领…

程序员如何保持与提升核心竞争力

一、引言  随着AIGC&#xff08;人工智能生成内容&#xff09;的快速发展&#xff0c;如chatgpt、midjourney、claude等大语言模型的涌现&#xff0c;AI辅助编程工具正逐渐成为程序员日常工作的得力助手。这一变革不仅对程序员的工作方式产生了深刻影响&#xff0c;也引发了关…

Kafka 下载安装及使用总结

1. 下载安装 官网下载地址&#xff1a;Apache Kafka 下载对应的文件 上传到服务器上&#xff0c;解压 tar -xzf kafka_2.13-3.7.0.tgz目录结果如下 ├── bin │ └── windows ├── config │ └── kraft ├── libs ├── licenses └── site-docs官方文档…

动态数据源多种实现方式及对比详细介绍

文章目录 动态数据源实现方式1. 概述2. 动态数据源实现方式2.1 基于 AbstractRoutingDataSource 实现动态数据源2.2 基于 Spring AOP 实现动态数据源2.3 基于 TransactionManager 实现动态数据源2.4 通过数据库中间件实现动态数据源&#xff08;ShardingSphere、MyCAT&#xff…

探索 Go 语言 container 包:强大容器的魔法世界

《探索 Go 语言 container 包:强大容器的魔法世界》 在 Go 语言的世界里,container包就像是一个神奇的宝库,里面藏着各种强大的容器,为开发者提供了高效的数据存储和操作方式。让我们一起揭开这个宝库的神秘面纱,探索container包中的那些容器。 一、container包简介 co…

将成功请求的数据 放入apipost接口测试工具,发送给后端后,部分符号丢失

将成功请求的数据 放入apipost接口测试工具&#xff0c;发送给后端后&#xff0c;部分符号丢失 apipost、接口测试、符号、丢失、错乱、变成空格背景 做CA对接&#xff0c;保存CA系统的校验数据&#xff0c;需要模仿前端请求调起接口&#xff0c;以便测试功能完整性。 问题描…

MySQL:事务隔离级别

SQL 标准定义了四个隔离级别&#xff1a; READ-UNCOMMITTED(读取未提交) &#xff1a;最低的隔离级别&#xff0c;允许读取尚未提交的数据变更&#xff0c;可能会导致脏读、幻读或不可重复读。READ-COMMITTED(读取已提交) &#xff1a;允许读取并发事务已经提交的数据&#xf…

Flink Task 日志文件隔离

Flink Task 日志文件隔离 任务在启动时会先通过 MdcUtils 启动一个 slf4j 的 MDC 环境&#xff0c;然后将 jobId 添加到 slf4j 的 MDC 容器中&#xff0c;随后任务输出的日志都将附带 joid。 MDC 介绍如下&#xff1a; MDC ( Mapped Diagnostic Contexts )&#xff0c;它是一个…

深度学习:(六)激活函数的选择与介绍

激活函数 之前使用的 a σ ( z ) a\sigma(z) aσ(z) &#xff0c;其中 σ ( ) \sigma(~) σ( ) 便是激活函数。 在神经网络中&#xff0c;不同层的激活函数可以不同。 在学习中&#xff0c;一般以 g ( z ) g(z) g(z) 来表示激活函数。 为什么需要(线性)激活函数&#xff…

K8s容器运行时,移除Dockershim后存在哪些疑惑?

K8s容器运行时&#xff0c;移除Dockershim后存在哪些疑惑&#xff1f; 大家好&#xff0c;我是秋意零。 K8s版本截止目前&#xff08;24/09&#xff09;已经发布到了1.31.x版本。早在K8s版本从1.24.x起&#xff08;22/05&#xff09;&#xff0c;默认的容器运行时就不再是Doc…

暑假考研集训营游记

文章目录 摘要&#xff1a;1.对各大辅导机构考研封闭集训营的一些个人看法&#xff1a;2.对于考研原因一些感想&#xff1a;结语 摘要&#xff1a; Ashy在暑假的时候参加了所在辅导班的为期一个月的考研封闭集训营&#xff0c;有了一些全新的感悟&#xff0c;略作记录。 1.对…

【SpringBoot】97、SpringBoot中使用EasyExcel导出/导入数据

1、EasyExcel Java 解析、生成 Excel 比较有名的框架有 Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi 有一套 SAX 模式的 API 可以一定程度的解决一些内存溢出的问题,但 POI 还是有一些缺陷,比如 07 版 Excel 解压缩以及解压后存储都是在内存中完成的,…

linux-系统备份与恢复-系统恢复

Linux 系统备份与恢复&#xff1a;系统恢复 1. 概述 Linux 系统的恢复是系统管理的重要组成部分&#xff0c;它指的是在系统崩溃、硬件故障、误操作或安全问题后&#xff0c;恢复系统到可用状态的过程。良好的系统恢复计划可以有效避免数据丢失和业务中断&#xff0c;并确保系…

ESP32配网接入Wifi

1 ESP32的两种模式 AP模式:ESP32可以作为热点,手机和电脑等设备接入使用。 STA模式:ESP32可以作为作为客户端接入其他网络中。 2 流程 step1: ESP32上电后进入STA模式,尝试看能够接入网络 step2: 如何连接成功,则正常运行。如何连接超时,则自动进入AP模式,设置AP热点…

算法之搜索--最长公共子序列LCS

最长公共子序列&#xff08;longest common sequence&#xff09;:可以不连续 最长公共子串&#xff08;longest common substring&#xff09;&#xff1a;连续 demo for (int i 1;i<lena;i){for (int j 1;j<lenb;j){if(a[i-1]b[j-1]){dp[i][j]dp[i-1][j-1]1;}el…

Qt (17)【Qt 文件操作 读写保存】

阅读导航 引言一、Qt文件概述二、输入输出设备类三、文件读写类四、文件和目录信息类五、自定义“记事本” 引言 在上一篇文章中&#xff0c;我们学习了Qt的事件处理机制&#xff0c;知道了如何响应用户的操作。但应用程序常常还需要处理文件&#xff0c;比如读写数据。所以&a…

python爬虫初体验(一)

文章目录 1. 什么是爬虫&#xff1f;2. 为什么选择 Python&#xff1f;3. 爬虫小案例3.1 安装python3.2 安装依赖3.3 requests请求设置3.4 完整代码 4. 总结 1. 什么是爬虫&#xff1f; 爬虫&#xff08;Web Scraping&#xff09;是一种从网站自动提取数据的技术。简单来说&am…