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.配置运行…

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

深度剖析&#xff1a;大模型AI时代下的推理路径创新应用方法论 随着大规模预训练模型&#xff08;Large Pretrained Models, LPMs&#xff09;和生成式人工智能的迅速发展&#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官方文档…

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…

算法之搜索--最长公共子序列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…

指针修仙之实现qsort

文章目录 回调函数什么是回调函数回调函数的作用 库函数qsort使用qsort函数排序整形使用qsort函数排序结构体 qsort函数模拟实现说明源码and说明 回调函数 什么是回调函数 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数…

Sigmoid引发的梯度消失爆炸及ReLU引起的神经元参数失效问题思考

Sigmoid和ReLU激活函数思考&#xff09; 引文Sigmoid函数梯度消失问题梯度爆炸问题解决方案 ReLU函数简化模型示例场景设定前向传播对反向传播的影响总结 内容精简版 引文 梯度消失和梯度爆炸是神经网络训练中常见的两个问题&#xff0c;特别是在使用Sigmoid激活函数时。这些问…

后端-navicat查找语句(单表与多表)

表格字段设置如图 语句&#xff1a; 1.输出 1.输出name和age列 SELECT name,age from student 1.2.全部输出 select * from student 2.where子语句 1.运算符&#xff1a; 等于 >大于 >大于等于 <小于 <小于等于 ! <>不等于 select * from stude…

torch模型量化方法总结

0.概述 模型训练完成后的参数为float或double类型,而装机(比如车载)后推理预测时,通常都会预先定点(量化)为int类型参数,相应的推理的精度会有少量下降,但不构成明显性能下降,带来的结果是板端部署的可能性,推理的latency明显降低,本文对torch常用的量化方法进行总…

JavaEE: 创造无限连接——网络编程中的套接字

文章目录 Socket套接字TCP和UDP的区别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP api的使用UDPDatagramSocketDatagramPacketInetSocketAddress练习 TCPServerSocketSocket练习 Socket套接字 Socket是计算机网络中的一种通信机制&#xff0…

【VLM小白指北 (1) 】An Introduction to Vision-Language Modeling

开一个新坑Vision-Language Modeling (VLM) &#xff0c;原文76页&#xff0c;慢慢更&#xff0c;for beginners&#xff0c;但也不能之前啥都不会啊。 原文链接&#xff1a;An Introduction to Vision-Language Modeling Introduction 存在的问题&#xff1a;将语言与视觉相…

ChatGPT 在国内使用的方法

AI如今很强大&#xff0c;聊聊天、写论文、搞翻译、写代码、写文案、审合同等等&#xff0c;ChatGPT 真是无所不能~ 作为一款出色的大语言模型&#xff0c;ChatGPT 实现了人类般的对话交流&#xff0c;最主要是能根据上下文进行互动。 接下来&#xff0c;我将介绍 ChatGPT 在国…

xhs 小红书 x-s web 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我…

《深度学习》PyTorch框架 优化器、激活函数讲解

目录 一、深度学习核心框架的选择 1、TensorFlow 1&#xff09;概念 2&#xff09;优缺点 2、PyTorch 1&#xff09;概念 2&#xff09;优缺点 3、Keras 1&#xff09;概念 2&#xff09;优缺点 4、Caffe 1&#xff09;概念 2&#xff09;优缺点 二、pytorch安装 1、安装 2、…

Linux操作系统:GCC(GNU Compiler Collection)编译器

在 Linux 系统中&#xff0c;gcc&#xff08;GNU Compiler Collection&#xff09;是一个非常强大的编译器&#xff0c;主要用于编译 C 语言程序。 除了基本的编译和链接命令外&#xff0c;gcc还提供了许多选项和功能。 以下是一些常用的 gcc命令及其功能&#xff1a; 1. 基本…

Python | Leetcode Python题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; class Solution:def strongPasswordChecker(self, password: str) -> int:n len(password)has_lower has_upper has_digit Falsefor ch in password:if ch.islower():has_lower Trueelif ch.isupper():has_upper Trueelif ch.isdi…