2020. 11. 30. 13:18ㆍProgramming/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.data
를 String.fromCharCodes
를 사용해서 문자열로 파싱하는 코드가 힌트다.
JavaScript를 사용해본 적이 있다면 String.fromCharCodes
가 어떤 녀석인지 대충 감이 올 수도 있다. JavaScript의 String.fromCharCodes는 각 배열요소가 0부터 65535(0xFFFF)까지로 구성되어있는 정수형 배열을 받아, 문자열로 파싱해주는 녀석이다. Dart에서도 크게 다르지 않다. 즉, datagram.data
는 각 배열요소가 0부터 65535(0xFFFF)까지로 구성된 정수형 배열이라는 얘기다. 즉 배열요소는 바이트 단위이다.
C로 작성된 서버랑 통신을 한다고 가정하면 Char
는 배열요소 하나를 사용해서 작성하면 된다. Int
는 배열요소 둘을 비트마스킹하면 된다. 다행히 스트링은 비트마스킹하지 않고 String.fromCharCodes
을 하면 된다. 와! 간단해!
물론 나는 멍청했기 때문에 String.fromCharCodes
를 보고도 '음, 정수형 배열이니까 직접 각 배열 요소에 비트마스킹을 하면 되겠군'이라고 생각했고, 실제로 비트마스킹 후에 와이어샤크로 패킷 캡처를 한 뒤에야 뭔가 이상하다는 걸 깨닳았다.
모쪼록 이 글을 보는 다른 분들은 이런 삽질을 하지 않기를 바라며, 글을 마무리 지어본다. ^ ㅈ^)