Flutter 이용하여 TCP socket 연결 샘플 코드

fultter 이용하여 TCP socket 접속을 해보겠습니다.

본 블로그에서 만들려는 flutter는 클라이언트 socket  입니다.

안드로이드와 IOS 에 적용가능하도록 개발합니다.

flutter 프로젝트를 생성

main.dart

import 'package:flutter/material.dart';

import 'views/view_test.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const ViewTest(),
    );
  }
}

views/view_test.dart

import 'dart:io';
import 'dart:typed_data';

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

const List<String> materialTypes = <String>['PLASTIC', 'GLASS'];

class ViewTest extends StatefulWidget {
  const ViewTest({Key? key}) : super(key: key);

  @override
  State<ViewTest> createState() => _ViewTestState();
}

class _ViewTestState extends State<ViewTest> {
  String _distance = "";
  String _angle = "";
  String _status = "";
  String _message = "";

  Socket? _socket;
  final String _host = "220.72.212.xxx";
  final int _port = 25003;

  Future<void> _sendMessage(String message) async {
    print("Sent message $message");
    _socket!.write(message);
    await Future.delayed(const Duration(seconds: 1));
  }

  void _connect(String ip, int port) async {
    Socket? sock;

    try {
      sock =
      await Socket.connect(ip, port, timeout: const Duration(seconds: 3));

      _socket = sock;
      setState(() {
        _status = "Connected to $ip:$port.";
        _message = "";
      });

      // listen for responses from the server
      _socket!.listen(
        // handle data from the server
            (Uint8List data) {
          final serverResponse = String.fromCharCodes(data);
          setState(() {
            _message = serverResponse;
          });
          print(serverResponse);
        },

        // handle errors
        onError: (error) {
          setState(() {
            _status = "Disconnected.";
            _message = "Error: $error";
          });
          print("Error: $error");
          _socket!.destroy();
          _socket = null;
        },

        // handle server ending connection
        onDone: () {
          setState(() {
            _status = "Disconnected.";
            _message = 'Server left.';
          });
          print('Server left.');
          _socket!.destroy();
          _socket = null;
        },
      );
    } catch (e) {
      setState(() {
        _status = "Connection failed.";
        _message = e.toString();
      });
      print("Error: ${e.toString()}");
    }
  }

  void _disconnect() {
    if (_socket != null) _socket!.destroy();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Center(child: Text("Radar Test")),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 50.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  setState(() {
                    _status = "";
                    _message = "";
                  });
                  _disconnect();
                  _connect(_host, _port);
                },
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text(
                    _socket == null ? 'Connect' : 'Reconnect',
                    style: const TextStyle(fontSize: 22.0),
                  ),
                ),
              ),
              const SizedBox(height: 50.0),
              TextField(
                onChanged: (text) {
                  _distance = text;
                },
                keyboardType:
                const TextInputType.numberWithOptions(decimal: false),
                inputFormatters: <TextInputFormatter>[
                  FilteringTextInputFormatter.allow(
                    RegExp(r'[0-9]+'), // this regex allows only decimal numbers
                  )
                ],
                decoration: const InputDecoration(
                  hintText: '100',
                  border: UnderlineInputBorder(),
                  labelText: 'Distance',
                ),
              ),
              TextField(
                onChanged: (text) {
                  _angle = text;
                },
                keyboardType:
                const TextInputType.numberWithOptions(decimal: false),
                inputFormatters: <TextInputFormatter>[
                  FilteringTextInputFormatter.allow(
                    RegExp(r'[0-9]+'), // this regex allows only decimal numbers
                  )
                ],
                decoration: const InputDecoration(
                  hintText: '90',
                  border: UnderlineInputBorder(),
                  labelText: 'Angle',
                ),
              ),
              const SizedBox(height: 50.0),
              Text("Status: $_status"),
              Text("Message: $_message"),
            ],
          ),
        ),
      ),
      floatingActionButton: ElevatedButton(
        onPressed: _socket == null
            ? null
            : () {
          // test
          /*
          _sendMessage(
              '{"distance": ${_distance.isEmpty ? 100 : int.parse(_distance)}, "angle": ${_angle.isEmpty ? 90 : int.parse(_angle)}}'
          );
          */
          _sendMessage('Hello Server~~~');
        },
        child: const Padding(
          padding: EdgeInsets.all(8.0),
          child: Text(
            'Send Radar Distance',
            style: TextStyle(fontSize: 22.0),
          ),
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

flutter 실행

Connect 클릭

Send data

참고 https://stackoverflow.com/questions/73755997/flutter-tcp-socket-connection-fails-on-real-device