ZetCode

Dart ServerSocket

最后修改于 2025 年 4 月 4 日

Dart 中的 ServerSocket 类提供了 TCP 服务器功能。它在指定的端口和 IP 地址上监听传入的客户端连接。

ServerSocket 是 Dart dart:io 库的一部分,用于服务器端编程。它能够构建处理多个客户端的网络服务器。

基本定义

ServerSocket 代表一个监听的 TCP 套接字,它接受传入的连接。每个连接都会创建一个 Socket 对象。

主要特性包括异步操作、地址绑定和连接管理。它是 Dart 应用程序中网络服务器的基础。

基本回显服务器

此示例创建了一个简单的回显服务器,它将收到的消息发送回去。

main.dart
import 'dart:io';

void main() async {
  var server = await ServerSocket.bind('127.0.0.1', 4040);
  print('Echo server listening on ${server.address}:${server.port}');

  await for (var socket in server) {
    socket.listen(
      (data) {
        print('Received: ${String.fromCharCodes(data)}');
        socket.add(data); // Echo back
      },
      onDone: () => print('Client disconnected'),
    );
  }
}

我们将服务器绑定到本地主机端口 4040,并异步处理每个客户端连接。服务器会回显任何收到的数据并记录客户端断开连接。

$ dart main.dart
Echo server listening on 127.0.0.1:4040
Received: Hello
Client disconnected

处理多个客户端

此示例演示了一个处理多个并发客户端的服务器。

main.dart
import 'dart:io';

void main() async {
  var server = await ServerSocket.bind('0.0.0.0', 4041);
  print('Multi-client server running on port ${server.port}');

  var clientCount = 0;
  
  await for (var socket in server) {
    clientCount++;
    print('Client $clientCount connected from ${socket.remoteAddress}');
    
    socket.listen(
      (data) => handleClientData(socket, data),
      onDone: () => print('Client $clientCount disconnected'),
    );
  }
}

void handleClientData(Socket socket, List<int> data) {
  var message = String.fromCharCodes(data).trim();
  print('Received: $message');
  socket.write('Echo: $message\n');
}

服务器跟踪已连接的客户端并独立处理它们的请求。每个客户端连接都在其自己的异步执行上下文中进行处理。

$ dart main.dart
Multi-client server running on port 4041
Client 1 connected from 127.0.0.1:54321
Received: Test message
Client 1 disconnected

广播服务器

此示例展示了一个将消息广播到所有已连接客户端的服务器。

main.dart
import 'dart:io';
import 'dart:async';

void main() async {
  var server = await ServerSocket.bind('127.0.0.1', 4042);
  print('Broadcast server started on port ${server.port}');

  var clients = <Socket>[];
  
  server.listen((socket) {
    clients.add(socket);
    print('New client connected (${clients.length} total)');
    
    socket.listen(
      (data) => broadcast(clients, data),
      onDone: () {
        clients.remove(socket);
        print('Client disconnected (${clients.length} remaining)');
      },
    );
  });

  // Broadcast periodic messages
  Timer.periodic(Duration(seconds: 5), (_) {
    if (clients.isNotEmpty) {
      broadcast(clients, 'Server time: ${DateTime.now()}\n'.codeUnits);
    }
  });
}

void broadcast(List<Socket> clients, List<int> message) {
  for (var client in clients) {
    client.add(message);
  }
}

服务器维护一个已连接客户端列表,并将消息广播给所有客户端。它还发送定期的时间更新并管理客户端断开连接。

$ dart main.dart
Broadcast server started on port 4042
New client connected (1 total)
Client disconnected (0 remaining)

带 SSL 的安全服务器

此示例演示了使用 SSL/TLS 加密创建安全服务器。

main.dart
import 'dart:io';

void main() async {
  var context = SecurityContext()
    ..useCertificateChain('certificate.pem')
    ..usePrivateKey('key.pem');
  
  var server = await SecureServerSocket.bind(
    '0.0.0.0', 
    4043,
    context,
  );
  
  print('Secure server listening on port ${server.port}');
  
  await for (var socket in server) {
    socket.listen(
      (data) {
        var message = String.fromCharCodes(data);
        print('Secure message: $message');
        socket.write('SECURE: $message');
      },
      onDone: () => print('Secure client disconnected'),
    );
  }
}

我们使用证书文件创建安全上下文并绑定安全套接字。服务器在保持相同 API 的同时处理加密通信。

$ dart main.dart
Secure server listening on port 4043
Secure message: Test
Secure client disconnected

连接限制和超时

此示例展示了如何实现连接限制和超时。

main.dart
import 'dart:io';
import 'dart:async';

void main() async {
  var server = await ServerSocket.bind('127.0.0.1', 4044);
  print('Managed server started with connection limits');
  
  var activeConnections = 0;
  const maxConnections = 3;
  
  await for (var socket in server) {
    if (activeConnections >= maxConnections) {
      socket.write('Server busy. Try again later.\n');
      socket.close();
      continue;
    }
    
    activeConnections++;
    print('New connection ($activeConnections/$maxConnections)');
    
    // Set timeout
    var timer = Timer(Duration(seconds: 30), () {
      socket.write('Connection timeout\n');
      socket.close();
    });
    
    socket.listen(
      (data) {
        timer.cancel(); // Reset timeout on activity
        timer = Timer(Duration(seconds: 30), () => socket.close());
        socket.add(data);
      },
      onDone: () {
        timer.cancel();
        activeConnections--;
        print('Connection closed ($activeConnections/$maxConnections)');
      },
    );
  }
}

服务器强制执行最大连接限制并实现空闲超时。每个连接有 30 秒的非活动时间,之后将被自动关闭。

$ dart main.dart
Managed server started with connection limits
New connection (1/3)
Connection closed (0/3)

最佳实践

来源

Dart ServerSocket 文档

本教程通过实际示例介绍了 Dart 的 ServerSocket 类,包括基本服务器、安全连接和高级连接管理。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Dart 教程