UDP 라이브러리를 통해 Flutter(Dart)에서 브로드캐스팅을 해보자

2020. 11. 30. 13:18Programming/Flutter

반응형

UDP 라이브러리를 통해 Flutter(Dart)에서 브로드캐스팅을 해보자

pub.dev에 등록된 라이브러리 중 UDP 라이브러리를 사용하면, 플러터에서도 쉽게 브로드캐스팅이 가능하다. UDP 라이브러리 페이지를 확인해보자.

인스톨 페이지에 나와있는대로 pubspec.yaml의 dependencies에 udp라이브러리를 등록하고, flutter pub get을 입력해주자. 라이브러리가 설치될 것이다.

dependencies:
  udp: ^3.0.3

예제 페이지에 나와있는대로, example/udp_example.dart를 확인해보면 쉽게 브로드캐스팅이 가능하다는 것을 알 수 있다.

import 'dart:io';

import 'package:udp/udp.dart';

main() async {
  // creates a UDP instance and binds it to the first available network
  // interface on port 65000.
  var sender = await UDP.bind(Endpoint.any(port: Port(65000)));

  // send a simple string to a broadcast endpoint on port 65001.
  var dataLength = await sender.send(
      "Hello World!".codeUnits, Endpoint.broadcast(port: Port(65001)));

  stdout.write("${dataLength} bytes sent.");

  // creates a new UDP instance and binds it to the local address and the port
  // 65002.
  var receiver = await UDP.bind(Endpoint.loopback(port: Port(65002)));

  // receiving\listening
  await receiver.listen((datagram) {
    var str = String.fromCharCodes(datagram.data);
    stdout.write(str);
  }, timeout: Duration(seconds: 20));

  // close the UDP instances and their sockets.
  sender.close();
  receiver.close();
}

예제 코드의 내용은 65001 포트로 Hello World!라는 메시지를 브로드캐스팅한 뒤, 65002 포트로 들어오는 메시지를 20초간 수신 대기한다. 만약 65001 포트를 수신하고 있던 서버가 Hello World!라는 메시지를 받고 65002포트에 응답하면, 문자열이 출력될 것이다. 와! 간단!

어라, 그런데 수신을 받은 서버가 문자열이 아닌 데이터를 전송하면 어떻게 해야할까? 또, 브로드캐스팅 할 때 문자열이 아닌 데이터를 전송하려면 어떻게 해야할까? receiver.listen에서 datagram.dataString.fromCharCodes를 사용해서 문자열로 파싱하는 코드가 힌트다.

JavaScript를 사용해본 적이 있다면 String.fromCharCodes가 어떤 녀석인지 대충 감이 올 수도 있다. JavaScript의 String.fromCharCodes는 각 배열요소가 0부터 65535(0xFFFF)까지로 구성되어있는 정수형 배열을 받아, 문자열로 파싱해주는 녀석이다. Dart에서도 크게 다르지 않다. 즉, datagram.data는 각 배열요소가 0부터 65535(0xFFFF)까지로 구성된 정수형 배열이라는 얘기다. 즉 배열요소는 바이트 단위이다.

C로 작성된 서버랑 통신을 한다고 가정하면 Char는 배열요소 하나를 사용해서 작성하면 된다. Int는 배열요소 둘을 비트마스킹하면 된다. 다행히 스트링은 비트마스킹하지 않고 String.fromCharCodes을 하면 된다. 와! 간단해!

물론 나는 멍청했기 때문에 String.fromCharCodes를 보고도 '음, 정수형 배열이니까 직접 각 배열 요소에 비트마스킹을 하면 되겠군'이라고 생각했고, 실제로 비트마스킹 후에 와이어샤크로 패킷 캡처를 한 뒤에야 뭔가 이상하다는 걸 깨닳았다.

모쪼록 이 글을 보는 다른 분들은 이런 삽질을 하지 않기를 바라며, 글을 마무리 지어본다. ^ ㅈ^)

반응형