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.xdnf.cn/news/144554.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Python】Anaconda插件:Sublime Text中的Python开发利器

上班的时候没人问我苦不苦&#xff0c;下班的时候总有人问为什么走这么早。 Anaconda 是一个专为Sublime Text打造的开源Python开发插件&#xff0c;旨在为开发者提供类似于IDE的丰富功能&#xff0c;提升Python编码效率。该插件提供了代码补全、语法检查、代码片段提示等多项…

【Elasticsearch】-图片向量化存储

需要结合深度学习模型 1、pom依赖 注意结尾的webp-imageio 包&#xff0c;用于解决ImageIO.read读取部分图片返回为null的问题 <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.7.0-0</versio…

Java线程---并发集合

List CopyOnWriteArrayList 并发修改时保证线程安全 通过ReentrantLock实现多个线程并发修改时的线程安全同步&#xff08;添加元素的同时&#xff0c;不允许删除&#xff09; 添加新元素&#xff1a;list.add("") 按照指定下标替换元素&#xff1a;list.set(index…

图像超分辨率技术代码分享

图像超分辨率是一种计算机视觉技术&#xff0c;用于提高图像的分辨率&#xff0c;即将低分辨率图像转换为高分辨率图像。这项技术主要应用在各种场合&#xff0c;如卫星图像处理、医学成像、视频增强和老照片修复等领域。 涉及到的技术包括&#xff1a; 扩散模型&#xff1a;这…

教你把PDF电子画册加背景音乐

​如何让您的PDF电子画册更具吸引力&#xff0c;让人一眼就能爱上它呢&#xff1f;答案就是为画册添加背景音乐&#xff01;添加背景音乐的PDF电子画册相较于普通画册&#xff0c;更能吸引读者的注意力&#xff0c;提升阅读体验。那么&#xff0c;如何为PDF电子画册添加背景音乐…

LVGL 控件之仪表盘(lv_meter)

目录 一、概述二、仪表盘部件1、添加刻度2、添加指针3、设置仪表的角度和仪表的范围4、装饰4.1 仪表指针图片4.2 仪表的指示刻度4.3 仪表弧线指示器 5、API 函数 一、概述 仪表盘部件可以非常灵活地展示数据&#xff0c;其功能包括显示弧形&#xff08;arcs&#xff09;、指针…

二叉树层序遍历的2种方法

方法1使用1个队列 class Solution {//使用一个队列&#xff0c;如果一个队列可以解决&#xff0c;那么就不需要使用2个数组//要最下面一层的最左边的结点&#xff0c;那么就先入右结点再入左结点public int findBottomLeftValue(TreeNode root) {TreeNode node root;Deque&l…

表格HTML

//test.html <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>表格与CSS分开示例</tit…

openEuler 22.03 LTS 安装JDK 8(亲测很简单的安装办法)

Oracle JDK从2019年4月16日起开始商业用途统统收费&#xff0c;也就是说只能使用2019年1月15发布的JDK 8u202免费版本&#xff0c;没有订阅&#xff08;交钱&#xff09;是没安全更新可用的&#xff0c;所以只能使用替代品OpenJDK、AdoptOpenJDK等发布版&#xff0c;那为什么不…

2024开学季好物推荐,这些开学必备好物不要错过!

又迎来了充满活力与梦想的开学季。不论是满怀憧憬步入新校园的新生&#xff0c;还是蓄势待发迎接新挑战的老生&#xff0c;为了帮助学生们更好地融入新学期的学习与生活中&#xff0c;我们特别策划了这份开学必备好物推荐指南。这里不仅汇集了能够提升学习效率的实用工具&#…

怎么快速批量生成静态二维码呢?批量静态码的3步在线生成技巧

怎么快速批量生成静态二维码呢&#xff1f;现在日常生活中的很多物品都会自己对应的二维码&#xff0c;扫码后可以查看相关物品的编码&#xff0c;那么怎么给一批物品批量生成对应的二维码呢&#xff1f;下面来教大家使用二维码批量生成工具制作静态码的方式&#xff0c;可以通…

2024/9/19 408大题专训之五段式指令流水线题型总结

结构冒险&#xff1a; 指令步骤&#xff1a;IF(取指令) ID(译码) EX&#xff08;执行、计算&#xff09;M&#xff08;访存&#xff09;WB&#xff08;写回&#xff09; 其中if和m都需要访问主存取指令和数据&#xff0c;如何解决呢&#xff1f;可以把cache分成数据cache指令…

【计网】从零开始使用TCP进行socket编程 ---服务端业务模拟Xshell

最糟糕的情况&#xff0c; 不是你出了错&#xff0c; 而是你没有面对出错的勇气。 从零开始使用TCP进行socket编程 1 通信过程的多版本实现1.1 多进程版本1.2 多线程版本 2 服务端业务模拟Xshell2.1 整体框架设计2.2 Command类设计 1 通信过程的多版本实现 在前一篇的文章…

内核是如何接收网络包的

1、数据如何从网卡到网络协议栈 1.1内核收包的过程 1、数据帧从外部网络到达网卡 2、网卡把数据帧从自己的缓存DMA(拷贝到)和内核共有的RingBuffer上 3、网卡发出硬中断通知CPU 4、CPU响应硬中断&#xff0c;简单处理后发出软中断 5、k’softirqd线程处理软中断&#xff0c;调…

ATGM331C-5T杭州中科微BDS/GNSS全星座定位授时模块应用领域

ATGM331C-5T 系列模块全部支持辅助 GNSS &#xff08;AGNSS&#xff09;功能&#xff1b;支持精确秒脉冲输出&#xff0c;脉冲上升沿与 UTC 时间对齐。 产品选型&#xff1a; 性能指标&#xff1a; 出色的定位导航功能&#xff0c;支持 BDS/GPS 卫星导航系统的单系统授时&#…

基于SpringBoot+Vue+MySQL的电子产品手机商城系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着科技的飞速发展&#xff0c;电子商务已成为现代生活不可或缺的一部分。尤其是电子产品领域&#xff0c;手机作为人们日常生活中必不可少的通讯与娱乐工具&#xff0c;其市场需求持续增长。为了满足广大消费者的购物需求&…

ssrf攻击fastcgi复现及环境搭建

目录 一、环境 二、开始操作 一、环境 网上自己找vulhub-master.zip&#xff0c;我这里没用docker&#xff0c;本地自己搭建的 二、开始操作 很明显的ssrf漏洞 很明显我们之前的协议file dict 很明显9000端口是开放的 我们还是用gopherus生成一下 我们环境机上很明显有PEAR…

git报错:无法读取远程分支 ‘origin‘ does not appear to be a git repository

问题分析 push上传的时候本地分支和远程分支断开连接 所以重新链接即可 排查问题 1. 查看是否有分支&#xff0c;检查分支是否正确 git branch -v 2. 查看连接是否断开&#xff0c;断开无内容展示 查看远程仓库详细信息&#xff0c;可看到仓库地址 git remote -v 解决…

华为OD机试 - 打印机队列 - 优先队列(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

数据恢复免费版工具大比拼,哪款才是你的“救星”?

在数字时代&#xff0c;数据的重要性不言而喻&#xff1b;如果不幸遇到了数据丢失的问题&#xff0c;不要慌张&#xff0c;我这里有四款免费的数据恢复工具推荐给你&#xff1b;希望能帮助你找到最适合自己的那款“救星”&#xff01; 一、福昕数据恢复 直通车&#xff08;粘…