Flutter-TCP基本编程

前言

本文将介绍基于dart:ioSocket,进行TCP基本编程,实现服务端与客户端的监听、连接、数据收发。

示例代码:https://gitee.com/tilongzs/flutter_study_demo/tree/master/socket_tcp_test

使用插件:

  • wifi_ip: ^0.0.1
  • buffer: ^1.0.7

服务端Socket

bind

通过ServerSocket.bind()来创建一个ServerSocket,参数指定为要bind的IP、端口。

_serverSocket = await ServerSocket.bind(InternetAddress.tryParse(serverIP), serverPot);

listen

通过_serverSocket.listen()来绑定Accept、Error、Close事件处理函数。

_serverSocket.listen(onAccept, onError: onSocketError, onDone: onServerListenSocketClose);

onAccept()处理来自客户端的连接,将与该客户端通信的Socket保存起来。注意,示例代码只保存最新的一个,实际编程时应该保存在某个列表里。

void onAccept(Socket socket) {
  _connectedSocket = socket;
  _connectedSocket.listen(onSocketRecv, onError: onSocketError, onDone: onSocketClose);

  printLog('有新客户端连接:${_connectedSocket.remoteAddress.address}:${_connectedSocket.remotePort}');
}

onSocketError()处理错误消息。

void onSocketError(Object error) {
  printLog('与服务端已连接的socket出现错误,error=${error.toString()}');
}

onServerListenSocketClose()处理停止监听消息,将ServerSocket变量设置为null

void onServerListenSocketClose() {
  _serverSocket = null;
  printLog('服务端停止监听');
}

已连接的客户端

_connectedSocket.listen(onSocketRecv, onError: onSocketError, onDone: onSocketClose);

已连接的客户端需要绑定Recv、Error、Close事件处理函数。

onSocketRecv()处理接收到的数据。这里假定客户端发来的是UTF8数据。

void onSocketRecv(Uint8List data) {
  var decoder = Utf8Decoder();
  String msg = decoder.convert(data); // 将UTF8数据解码
  printLog('收到:${data.length}字节数据 内容:$msg');
}

onSocketError()处理错误消息。

void onSocketError(Object error) {
  printLog('与服务端已连接的socket出现错误,error=${error.toString()}');
}

onSocketClose()处理客户端断开连接消息。注意,示例代码只保存最新的一个_connectedSocket ,实际编程时应该将其从某个列表里移除。

void onSocketClose() {
  _connectedSocket = null;
  printLog('断开连接');
}

发送数据

使用_connectedSocket.add(List<int> data)发送,这个函数不阻塞线程,但data发送之后不能修改。

onBtnSendMsg()示例发送UTF8数据。

void onBtnSendMsg() async {
  if (_sendMsgController.text.isNotEmpty) {
    if (_connectedSocket != null) {
      var encoder = Utf8Encoder(); // 创建UTF8转换器,以支持发送中文
      _connectedSocket.add(encoder.convert(_sendMsgController.text)); // 发送
    }

    _sendMsgController.text = '';
    setState(() {});
  }
}

onBtnSendBigBuffer()示例发送指定大小缓冲区的数据。

缓冲区可以使用Dart的ByteData,也可以使用推荐的插件buffer

void onBtnSendBigBuffer(){
 /* var dataWriter = ByteDataWriter();
  dataWriter.writeUint8(1); // 1个字节
  _connectedSocket.add(dataWriter.toBytes());*/

  var byteData = ByteData(1024*1024);
  _connectedSocket.add(byteData.buffer.asUint8List());
}

断开连接

断开已连接的客户端:

_connectedSocket.close();
_connectedSocket = null;

停止监听:

_serverSocket.close(); 
_serverSocket = null;

客户端Socket

connect

通过Socket.connect()创建一个连接服务端的socket,实现客户端与服务端的监听、连接、数据收发。

_connectedSocket = await Socket.connect(serverIP, serverPot,
    timeout: Duration(milliseconds: 500));

通过_connectedSocket.listen()来绑定Recv、Error、Close事件处理函数,与服务端相同。

_connectedSocket.listen(onSocketRecv, onError: onSocketError, onDone: onSocketClose);

断开连接

_connectedSocket.close();
_connectedSocket = null;

留下评论