Flutter TCP通信插件tcp_tunnel的使用
Flutter TCP通信插件tcp_tunnel的使用
标题
tcp_tunnel
内容
- pub包版本: pub/v/tcp_tunnel.svg
- Null Safety: dart.dev/null-safety
- Codecov: app.codecov.io/gh/gmpassos/tcp_tunnel
- Dart CI: github.com/gmpassos/tcp_tunnel/actions/workflows/dart.yml/badge.svg?branch=master
- GitHub Tag: github.com/gmpassos/tcp_tunnel/releases
- New Commits: github.com/gmpassos/tcp_tunnel/network
- Last Commits: github.com/gmpassos/tcp_tunnel/commits/master
- Pull Requests: github.com/gmpassos/tcp_tunnel/pulls
- Code Size: github.com/gmpassos/tcp_tunnel/blob/master/LICENSE
- License: github.com/dart-lang/stagehand/blob/master/LICENSE
动机
该库的主要动机是帮助开发人员在复杂的网络拓扑中开发服务器、客户端和服务。
使用方法
有三种类型的隧道可以结合使用:
-
本地端口重定向: 将
listenPort
(例如 3366)链接到localTargetPort
(例如 3306),实现双向数据流。Future<void> redirectLocalPort(int listenPort, int targetPort, {String targetHost = 'localhost'}) async { await TunnelLocalServer(listenPort, targetPort, targetHost: targetHost).start(); }
-
桥接隧道: 连接
listenPort1
和listenPort2
,实现数据流量交换。Future<void> bridgePorts(int listenPort1, int listenPort2) async { await TunnelBridge(listenPort1, listenPort2).start(); }
-
客户端隧道: 将
remoteHost:remotePort
链接到localTargetPort
,实现双向数据传输。Future<void> clientTunnel(String remoteHost, int remotePort, int localTargetPort) async { var tunnel = Tunnel.connect(remoteHost, remotePort, localTargetPort); tunnel.onClose = ( t) { // 关闭连接,尝试重新连接... }; }
CLI工具
你可以轻松地在任何支持Dart的平台上使用CLI工具 tcp_tunnel
。
激活CLI工具只需运行:
dart pub global activate tcp_tunnel
然后你可以为每个必要的场景创建隧道:
-
本地端口重定向:
tcp_tunnel local %listenPort %targetPort %targetHost
%targetHost
是可选的,默认值为localhost
。
-
桥接隧道:
tcp_tunnel bridge %listenPort1 %listenPort2
-
客户端隧道:
tcp_tunnel client %remoteHost %remotePort %localTargetPort
结合使用
要访问远程服务器X(没有公共地址)中的端口3306(MySQL):
-
在公共服务器Y(server-y.domain)上建立一个服务器桥接:
tcp_tunnel bridge 8035 8036
-
在私有服务器X(具有私有MySQL数据库的服务器)上运行客户端隧道:
tcp_tunnel client server-y.domain 8036 3306
-
运行mysql客户端指向隧道端口:
mysql -u myuser -p -h server-y.domain -P 8035
-
如果希望扩展配置,可以在上述重定向中建立一个本地端口:
tcp_tunnel local 3306 8035 server-y.domain
现在,只需访问本地端口3306即可,就像访问标准MySQL数据库一样。 实际上,这个本地端口连接到一个远程私有服务器。
mysql -u myuser -p -h localhost -P 3306
或者默认设置(与上述相同):
mysql -u myuser -p
安全性
请注意,隧道通信 未加密,且任何通过公共网络进行的连接都可能暴露其数据给潜在的安全风险。
特征和bug
请将功能请求和bug提交到 issue tracker。
作者
Graciliano M. Passos: gmpassos@GitHub
赞助
不要害羞,展示一些爱,成为我们的 GitHub赞助商。你的支持对我们来说意义重大,并且保持代码充满活力!☕✨
许可证
Dart免费开源许可证 https://github.com/dart-lang/stagehand/blob/master/LICENSE
示例代码
import 'dart:io';
import 'package:tcp_tunnel/tcp_tunnel.dart';
void main() async {
// 桥接:8035 <-> 8036
await bridgePorts(8035, 8036);
// 客户端:8036 <-> 3306
await clientTunnel('localhost', 8036, 3306);
// 客户端:3307 <-> 8035
await redirectLocalPort(3307, 8035);
///// 最终隧道:
// 3307 <-> 8035 <-> 8036 <-> 3306
}
Future<void> redirectLocalPort(int listenPort, int targetPort,
{String targetHost = 'localhost'}) async {
await TunnelLocalServer(listenPort, targetPort, targetHost: targetHost)
.start();
}
Future<void> bridgePorts(int listenPort1, int listenPort2) async {
await TunnelBridge(listenPort1, listenPort2).start();
}
Future<void> clientTunnel(
String remoteHost, int remotePort, int localTargetPort) async {
var tunnel = Tunnel.connect(remoteHost, remotePort, localTargetPort);
tunnel.onClose = (t) {
print('** Tunnel Closed');
exit(1);
};
}
更多关于Flutter TCP通信插件tcp_tunnel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter TCP通信插件tcp_tunnel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中进行TCP通信,tcp_tunnel
插件是一个非常有用的工具。下面是一个使用 tcp_tunnel
插件进行TCP通信的示例代码。该示例展示了如何建立TCP连接、发送和接收数据。
首先,确保在你的 pubspec.yaml
文件中添加 tcp_tunnel
依赖:
dependencies:
flutter:
sdk: flutter
tcp_tunnel: ^x.y.z # 请将x.y.z替换为最新版本号
然后运行 flutter pub get
来获取依赖。
接下来,在你的 Dart 代码中,你可以按照以下步骤使用 tcp_tunnel
插件:
import 'package:flutter/material.dart';
import 'package:tcp_tunnel/tcp_tunnel.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TcpTunnel? _tcpTunnel;
TextEditingController _controller = TextEditingController();
String _response = '';
@override
void initState() {
super.initState();
initTcpTunnel();
}
void initTcpTunnel() async {
_tcpTunnel = TcpTunnel(
host: 'example.com', // 替换为你的服务器地址
port: 12345, // 替换为你的服务器端口
);
_tcpTunnel!.connect();
_tcpTunnel!.dataStream.listen((data) {
setState(() {
_response = String.fromCharCodes(data);
});
});
_tcpTunnel!.errorStream.listen((error) {
print('Error: $error');
});
}
void _sendMessage() async {
if (_tcpTunnel!.isConnected) {
String message = _controller.text;
List<int> messageBytes = message.codeUnits;
_tcpTunnel!.sendData(messageBytes);
_controller.clear();
} else {
print('TCP Tunnel is not connected');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('TCP Tunnel Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(labelText: 'Message'),
maxLines: 4,
),
SizedBox(height: 16),
ElevatedButton(
onPressed: _sendMessage,
child: Text('Send Message'),
),
SizedBox(height: 16),
Text('Response:\n$_response'),
],
),
),
),
);
}
@override
void dispose() {
_tcpTunnel?.close();
_controller.dispose();
super.dispose();
}
}
代码解释:
- 依赖添加:在
pubspec.yaml
文件中添加tcp_tunnel
依赖。 - 初始化TCP连接:在
initState
方法中初始化TcpTunnel
对象,并连接到指定的服务器地址和端口。 - 数据监听:通过
_tcpTunnel!.dataStream.listen
监听从服务器接收到的数据,并更新UI。 - 发送消息:在
_sendMessage
方法中,将用户输入的消息发送到服务器。 - UI界面:使用
TextField
和ElevatedButton
创建一个简单的UI,用户可以输入消息并发送。 - 清理资源:在
dispose
方法中关闭TCP连接并释放资源。
请注意,tcp_tunnel
插件的具体用法可能会随着版本更新而有所变化,因此请查阅最新的文档和示例代码以确保兼容性。