簡體   English   中英

Flutter:在單個有狀態小部件中偵聽和寫入套接字

[英]Flutter: Listening and writing to a socket in a single stateful widget

我有一段時間沒有在 flutter 應用程序上工作過,也從未在套接字級應用程序上工作過。 我正在嘗試學習如何使單個有狀態小部件偵聽套接字。 小部件可以輕松地將數據寫入套接字。

我正在嘗試學習解決問題的方法,以便弄清楚如何組織我的應用程序。

編輯:我有一個草率的版本,所以更清楚我想要完成什么。

// Assume this will be stored in some BLoC 
// that will be available to any widget that needs it.
Socket socket;

void main() async {
  socket = await Socket.connect('192.168.139.194', 80);
  //can write to client with socket.write("...");

  socket.listen(handleClient);
  // handleClient takes care of responding to message from client

  runApp(MyApp(sock));
}

void handleClient(Uint8List data) {
  // Show the address and port of the client
  print('Connection from '
    '${socket.remoteAddress.address}:${socket.remotePort}');

  // Show what the client said
  print("client listen  : ${String.fromCharCodes(data).trim()}");

  // Send acknowledgement to client
  socket.write("Hello from simple server!\n");
}

您可以使用Socket.connect()連接客戶端的套接字,使用ServerSocket.bind()偵聽服務器端的傳入連接。 您可以使用socket.write(message);通過套接字發送數據。 , 並使用socket.listen(); .

示例客戶端代碼:

Socket.connect("localhost", 9999).then((socket) {
  print('client connected : ${socket.remoteAddress.address}:${socket.remotePort}');

  socket.listen((data) {
    print("client listen  : ${String.fromCharCodes(data).trim()}");
  }, onDone: () {
    print("client done");
    socket.destroy();
  });

  socket.write(message);
});

示例服務器代碼:

  void listen() {
    ServerSocket.bind(InternetAddress.anyIPv4, 9999).then((ServerSocket server) {
      server.listen(handleClient);
    });
  }

  void handleClient(Socket client) {
    print('server incoming connection from ${client.remoteAddress.address}:${client.remotePort}');
    client.listen((data) {
      print("server listen  : ${String.fromCharCodes(data).trim()}");
      setState(() {
        _incomingMessage = String.fromCharCodes(data).trim();
      });
    }, onDone: () {
      print("server done");
    });
    client.close();
  }

請參考: https://jamesslocum.com/blog/post/67566023889

您可以在 github 上找到客戶端服務器的完整源代碼


更新:如果您想使用相同的小部件可以聽和寫,您可以參考此代碼。 您應該開始在構造函數中偵聽套接字。

示例代碼:

import 'dart:io';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key) {
    listen();
  }

  void socketSend(String message) {
    Socket.connect("localhost", 9999).then((socket) {
      print('client connected : ${socket.remoteAddress.address}:${socket.remotePort}');

      socket.listen((data) {
        print("client listen  : ${String.fromCharCodes(data).trim()}");
      }, onDone: () {
        print("client done");
        socket.destroy();
      });

      socket.write(message);
    });
  }

  void listen() {
    ServerSocket.bind(InternetAddress.anyIPv4, 9999).then((ServerSocket server) {
      server.listen(handleClient);
    });
  }

  void handleClient(Socket client) {
    print('server incoming connection from ${client.remoteAddress.address}:${client.remotePort}');
    client.listen((data) {
      print("server listen  : ${String.fromCharCodes(data).trim()}");
    }, onDone: () {
      print("server done");
    });
    client.close();
  }

  @override
  Widget build(BuildContext context) {
    final myController = TextEditingController();

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text("socket test"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextField(controller: myController),
              ElevatedButton(onPressed: () => socketSend(myController.text), child: const Text("Send")),
            ],
          ),
        ),
      ),
    );
  }
} 

端口80也是HTTP的保留端口。 您不應使用此端口進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM