ZetCode

Dart RawSecureServerSocket

最后修改于 2025 年 4 月 4 日

Dart 中的 RawSecureServerSocket 类使用 TLS/SSL 提供了一个安全服务器套接字实现。它是 Dart dart:io 库的一部分,用于安全网络通信。

RawSecureServerSocket 实现了服务器和客户端之间的加密通信。它会自动处理 TLS 握手以及数据的加密/解密。

基本定义

RawSecureServerSocket 是一个服务器端套接字,它使用 TLS/SSL 进行安全通信。它会在指定的端口监听传入的客户端连接。

主要功能包括证书管理、加密和平台无关的安全通信。它是 RawServerSocket 的安全对应项。

基本安全服务器

此示例展示了一个监听连接的基本安全服务器。

main.dart
import 'dart:io';

void main() async {
  var context = SecurityContext()
    ..useCertificateChain('cert.pem')
    ..usePrivateKey('key.pem');
  
  var server = await RawSecureServerSocket.bind(
    'localhost', 8080, context);
  
  print('Secure server listening on port 8080');
  
  server.listen((client) {
    print('Client connected: ${client.remoteAddress}');
    client.writeEventsEnabled = true;
    client.write('Hello secure client!\n'.codeUnits);
    client.close();
  });
}

我们创建一个带有证书文件的 SecurityContext,然后绑定服务器套接字。服务器监听连接,并向每个客户端发送问候语。

$ dart main.dart
Secure server listening on port 8080

处理客户端数据

此示例演示了从安全客户端连接读取数据。

main.dart
import 'dart:io';

void main() async {
  var context = SecurityContext()
    ..useCertificateChain('cert.pem')
    ..usePrivateKey('key.pem');
  
  var server = await RawSecureServerSocket.bind(
    'localhost', 8080, context);
  
  server.listen((client) {
    client.listen(
      (data) {
        var message = String.fromCharCodes(data);
        print('Received: $message');
        client.write('Echo: $message'.codeUnits);
      },
      onDone: () => client.close()
    );
  });
}

服务器会将从客户端接收到的任何数据回显回去。每个客户端连接都有自己的数据流,我们可以监听该数据流以接收传入的消息。

$ dart main.dart
Received: Hello server

客户端身份验证

此示例展示了如何要求客户端证书进行身份验证。

main.dart
import 'dart:io';

void main() async {
  var context = SecurityContext()
    ..useCertificateChain('server.pem')
    ..usePrivateKey('server_key.pem')
    ..setTrustedCertificates('client_ca.pem')
    ..requireClientCertificate();
  
  var server = await RawSecureServerSocket.bind(
    'localhost', 8080, context);
  
  server.listen((client) {
    print('Client certificate: ${client.peerCertificate}');
    client.write('Authenticated!\n'.codeUnits);
    client.close();
  });
}

我们通过调用 requireClientCertificate 来配置服务器以要求客户端证书。然后,服务器可以通过 peerCertificate 访问客户端的证书。

$ dart main.dart
Client certificate: [Certificate details...]

处理多个客户端

此示例演示了如何处理多个并发客户端连接。

main.dart
import 'dart:io';

void main() async {
  var context = SecurityContext()
    ..useCertificateChain('cert.pem')
    ..usePrivateKey('key.pem');
  
  var server = await RawSecureServerSocket.bind(
    'localhost', 8080, context);
  
  var clientCount = 0;
  
  server.listen((client) {
    var id = ++clientCount;
    print('Client $id connected');
    
    client.listen(
      (data) {
        print('Client $id: ${String.fromCharCodes(data)}');
      },
      onDone: () {
        print('Client $id disconnected');
        client.close();
      }
    );
  });
}

服务器使用唯一 ID 来跟踪每个客户端,并独立处理它们的连接。这种模式对于聊天服务器或多人游戏非常有用。

$ dart main.dart
Client 1 connected
Client 1: Hello
Client 1 disconnected

自定义协议实现

此示例展示了如何在安全套接字上实现自定义协议。

main.dart
import 'dart:io';

class SecureProtocolServer {
  final RawSecureServerSocket server;
  
  SecureProtocolServer(this.server) {
    server.listen(_handleClient);
  }
  
  void _handleClient(RawSecureSocket client) {
    var buffer = <int>[];
    
    client.listen(
      (data) {
        buffer.addAll(data);
        
        // Check for complete message (ends with newline)
        if (buffer.contains(10)) {
          var message = String.fromCharCodes(buffer);
          print('Received: $message');
          
          // Process message and respond
          var response = 'Processed: ${message.trim()}';
          client.write(response.codeUnits);
          
          buffer.clear();
        }
      },
      onDone: () => client.close()
    );
  }
}

void main() async {
  var context = SecurityContext()
    ..useCertificateChain('cert.pem')
    ..usePrivateKey('key.pem');
  
  var server = await RawSecureServerSocket.bind(
    'localhost', 8080, context);
  
  SecureProtocolServer(server);
  print('Custom protocol server running');
}

我们实现了一个简单的协议,其中消息以换行符结尾。服务器缓冲数据,直到接收到完整消息,然后对其进行处理。

$ dart main.dart
Custom protocol server running
Received: Test message

最佳实践

来源

Dart RawSecureServerSocket 文档

本教程介绍了 Dart 的 RawSecureServerSocket 类,并通过实际示例展示了安全通信、客户端身份验证和协议实现。

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Dart 教程