Flutter如何在web端实现局域网发送文件

我想在Flutter开发的Web应用中实现局域网内文件传输功能,但不太清楚具体该怎么做。目前遇到以下几个问题:

  1. Web环境下如何检测同一局域网内的其他设备?
  2. Flutter Web是否支持直接通过TCP/UDP进行点对点文件传输?
  3. 如果无法直接使用底层协议,有没有推荐的库或替代方案?
  4. 传输过程中如何实现进度显示和断点续传? 希望有经验的朋友能分享一下实现思路或示例代码,最好能兼容主流浏览器。
2 回复

Flutter Web可使用WebSocket或HTTP实现局域网文件传输。步骤如下:

  1. 创建WebSocket服务器和客户端;
  2. 将文件分块传输;
  3. 接收端重组文件。 注意:需处理跨域和浏览器文件API限制。

更多关于Flutter如何在web端实现局域网发送文件的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter Web中实现局域网文件发送,可以通过WebSocket或HTTP实现点对点传输。以下是使用WebSocket的完整方案:

核心实现步骤

1. 添加依赖

dependencies:
  web_socket_channel: ^2.4.0
  http: ^1.1.0

2. WebSocket服务端代码

import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:web_socket_channel/io.dart';

class FileServer {
  late HttpServer _server;
  final Map<String, WebSocketChannel> _clients = {};
  
  Future<void> start(int port) async {
    _server = await HttpServer.bind(InternetAddress.anyIPv4, port);
    print('服务器启动在: ${_server.address.host}:$port');
    
    await for (var request in _server) {
      if (WebSocketTransformer.isUpgradeRequest(request)) {
        var socket = await WebSocketTransformer.upgrade(request);
        var channel = IOWebSocketChannel(socket);
        _handleClient(channel);
      }
    }
  }
  
  void _handleClient(WebSocketChannel channel) {
    String clientId = DateTime.now().millisecondsSinceEpoch.toString();
    _clients[clientId] = channel;
    
    channel.stream.listen(
      (message) {
        // 处理文件传输
        if (message is List<int>) {
          _broadcastFile(message, clientId);
        }
      },
      onDone: () => _clients.remove(clientId),
    );
  }
  
  void _broadcastFile(List<int> fileData, String senderId) {
    _clients.forEach((id, client) {
      if (id != senderId) {
        client.sink.add(fileData);
      }
    });
  }
}

3. 客户端发送文件

import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:web_socket_channel/io.dart';
import 'package:file_picker/file_picker.dart';

class FileSender {
  late WebSocketChannel _channel;
  
  Future<void> connect(String serverUrl) async {
    _channel = IOWebSocketChannel.connect(serverUrl);
  }
  
  Future<void> sendFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles();
    
    if (result != null) {
      PlatformFile file = result.files.first;
      Uint8List fileBytes = file.bytes!;
      
      // 发送文件数据
      _channel.sink.add(fileBytes);
    }
  }
}

4. 客户端接收文件

class FileReceiver {
  late WebSocketChannel _channel;
  
  Future<void> connect(String serverUrl) async {
    _channel = IOWebSocketChannel.connect(serverUrl);
    
    _channel.stream.listen((data) {
      if (data is List<int>) {
        _saveFile(data);
      }
    });
  }
  
  void _saveFile(List<int> fileData) {
    // 创建下载链接
    final blob = html.Blob([fileData]);
    final url = html.Url.createObjectUrlFromBlob(blob);
    final anchor = html.AnchorElement(href: url)
      ..download = 'received_file'
      ..click();
    
    html.Url.revokeObjectUrl(url);
  }
}

使用示例

// 启动服务器
final server = FileServer();
await server.start(8080);

// 客户端连接
final sender = FileSender();
await sender.connect('ws://192.168.1.100:8080');
await sender.sendFile();

注意事项

  1. 局域网发现:使用network_info_plus包获取本地IP
  2. 大文件处理:需要分块传输,避免内存溢出
  3. 错误处理:添加适当的异常捕获和重连机制
  4. 安全性:在生产环境中添加身份验证

这个方案实现了基本的局域网文件传输功能,可以根据实际需求进行扩展和优化。

回到顶部