2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterでTCP通信

Posted at

Flutter Dashロボット

FlutterでTCP通信例を作ったので、備忘録です。
Flutter Dashさんが左右に動く装置を、遠隔操作します。
TCP通信なのか、TELNET通信なのか、正確な名称はよくわかりませんが、
TELNETで接続後、コマンド「left」「right」で、Dashさんが左右に動かすことができる装置をコントロールします。

通信部分は以下を参照しました。
https://medium.com/flutter-community/working-with-sockets-in-dart-15b443007bc9

通信仕様

項目 設定値
サーバーIP 127.0.0.1
ポート 5000
ログインID なし
パスワード なし
終端文字 \r\n

操作コマンド

コマンド 説明
left Dashさんが左に動きます
right Dashさんが右に動きます

操作方法

1 装置を起動する

Sheet1_B43.png

2 コントローラを起動する

Sheet1_B52.png

3 コントローラからConnectする

4 ボタンが有効になったら、左右に動かす

Sheet1_B67.png

コントローラ

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

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => TcpClient(),
      child: MaterialApp(
        home: ClientPage(),
        debugShowCheckedModeBanner: false,
      ),
    ),
  );
}

class TcpClient with ChangeNotifier {
  Socket? socket;
  bool isConnect = false;
  String serverResponse = '';
  Future<void> connect() async {
    try {
      socket = await Socket.connect('127.0.0.1', 5000);
    } catch (e) {
      throw Exception('connect error!!');
    }
    // connect server
    isConnect = true;
    notifyListeners();

    // listen for responses from the server
    socket?.listen(
      // handle data from the server
      (Uint8List data) {
        serverResponse = String.fromCharCodes(data).replaceAll('\r\n', '');
        notifyListeners();
      },
      // handle errors
      onError: (error) {
        socket?.destroy();
      },
      // handle server ending connection
      onDone: () {
        isConnect = false;
        socket?.destroy();
        notifyListeners();
      },
    );
  }

  Future<void> sendMessage(String message) async {
    socket?.write(message);
    await Future.delayed(Duration(milliseconds: 500));
  }
}

/// Fcontroller main page
class ClientPage extends StatefulWidget {
  const ClientPage({Key? key}) : super(key: key);
  @override
  _ClientPageState createState() => _ClientPageState();
}

class _ClientPageState extends State<ClientPage> {
  @override
  Widget build(BuildContext context) {
    var client = context.read<TcpClient>();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Fobot controller'),
      ),
      body: Row(
        children: [
          TextButton(
              onPressed: () {
                client.connect();
              },
              child: Text('connect')),
          const Padding(padding: EdgeInsets.all(3)),
          ElevatedButton(
              child: Icon(Icons.arrow_left_rounded),
              onPressed: context.watch<TcpClient>().isConnect
                  ? () {
                      client.sendMessage('left');
                    }
                  : null),
          const Padding(padding: EdgeInsets.all(3)),
          ElevatedButton(
              child: Icon(Icons.arrow_right_rounded),
              onPressed: context.watch<TcpClient>().isConnect
                  ? () {
                      client.sendMessage('right');
                    }
                  : null),
        ],
      ),
    );
  }
}

装置

コントローラの動作確認用に作ったもの

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

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => TcpServer(),
      child: MaterialApp(
        home: ServerPage(),
      ),
    ),
  );
}

/// network server
class TcpServer with ChangeNotifier {
  String request = '';

  /// constructor
  TcpServer() {
    start();
  }

  void start() async {
    final server = await ServerSocket.bind("127.0.0.1", 5000);
    server.listen((client) {
      client.listen(
        (Uint8List data) async {
          request = String.fromCharCodes(data).replaceAll('\r\n', '');
          client.write('ret:' + request + '\r\n');
          notifyListeners();
        },
        // handle errors
        onError: (error) {
          client.close();
        },
        // handle the closing the connection
        onDone: () {
          client.close();
        },
      );
    });
  }
}

/// fobot server main page
class ServerPage extends StatefulWidget {
  const ServerPage({Key? key}) : super(key: key);

  @override
  _ServerPageState createState() => _ServerPageState();
}

class _ServerPageState extends State<ServerPage> {
  final positionMax = 10;
  int position = 2;

  @override
  Widget build(BuildContext context) {
    var req = context.watch<TcpServer>().request;
    if (req == 'left') {
      position = position - 1 < 0 ? 0 : position - 1;
    } else if (req == 'right') {
      position = position >= positionMax - 1 ? positionMax - 1 : position + 1;
    }
    return Scaffold(
        body: Row(
            children: List.generate(positionMax, (index) {
      return Container(
          decoration: BoxDecoration(
            border: Border.all(color: Colors.black),
          ),
          child: Icon(position == index ? Icons.flutter_dash : null));
    })));
  }
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?