ZetCode

Dart RawSynchronousSocket

最后修改于 2025 年 4 月 4 日

Dart 中的 RawSynchronousSocket 类为底层网络编程提供了同步套接字操作。它是 Dart dart:io 库的一部分。

与异步套接字不同,RawSynchronousSocket 会阻塞直到操作完成。这使其适用于需要同步行为的特定用例。

基本定义

RawSynchronousSocket 代表一个同步 TCP 套接字连接。它允许无回调或 Future 的阻塞读/写操作。

主要功能包括同步数据传输、直接字节访问和连接管理。它通常用于专业场景。

创建同步套接字

此示例展示了如何创建同步套接字连接。

main.dart
import 'dart:io';

void main() {
  var socket = RawSynchronousSocket.connectSync('example.com', 80);
  
  if (socket != null) {
    print('Connected to ${socket.address.address}:${socket.port}');
    socket.closeSync();
  } else {
    print('Connection failed');
  }
}

我们创建一个到 Web 服务器的同步 TCP 连接。connectSync 方法会阻塞直到连接成功或失败。完成后务必关闭套接字。

$ dart main.dart
Connected to 93.184.216.34:80

同步读取操作

此示例演示了从套接字同步读取。

main.dart
import 'dart:io';

void main() {
  var socket = RawSynchronousSocket.connectSync('example.com', 80);
  if (socket == null) return;
  
  var request = 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n';
  socket.writeFromSync(request.codeUnits);
  
  var buffer = List.filled(1024, 0);
  var bytesRead = socket.readIntoSync(buffer, 0, buffer.length);
  
  print('Read $bytesRead bytes:');
  print(String.fromCharCodes(buffer.sublist(0, bytesRead)));
  
  socket.closeSync();
}

我们发送一个 HTTP 请求并同步读取响应。readIntoSync 方法会阻塞直到有数据可用。缓冲区存储接收到的字节。

$ dart main.dart
Read 1024 bytes:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
...

同步写入操作

此示例展示了向套接字同步写入。

main.dart
import 'dart:io';

void main() {
  var socket = RawSynchronousSocket.connectSync('localhost', 8080);
  if (socket == null) return;
  
  var message = 'Hello, server!\n';
  var bytesWritten = socket.writeFromSync(message.codeUnits);
  
  print('Wrote $bytesWritten bytes to socket');
  
  socket.closeSync();
}

我们连接到一个本地服务器并同步写入数据。writeFromSync 方法会阻塞直到所有字节都被写入。它返回发送的字节数。

$ dart main.dart
Wrote 15 bytes to socket

处理多个操作

此示例演示了对套接字执行多个同步操作。

main.dart
import 'dart:io';

void main() {
  var socket = RawSynchronousSocket.connectSync('time.nist.gov', 13);
  if (socket == null) return;
  
  var buffer = List.filled(256, 0);
  var totalBytes = 0;
  
  while (true) {
    var bytesRead = socket.readIntoSync(buffer, 0, buffer.length);
    if (bytesRead <= 0) break;
    
    totalBytes += bytesRead;
    print(String.fromCharCodes(buffer.sublist(0, bytesRead)));
  }
  
  print('Total bytes received: $totalBytes');
  socket.closeSync();
}

我们连接到一个 daytime 服务器并在循环中读取数据。readIntoSync 调用会阻塞直到数据到达。当连接关闭时,循环退出。

$ dart main.dart
59335 23-04-25 12:34:56 00 0 0 123.5 UTC(NIST) 
Total bytes received: 51

错误处理

此示例展示了同步套接字的正确错误处理。

main.dart
import 'dart:io';

void main() {
  try {
    var socket = RawSynchronousSocket.connectSync('invalid.host', 80);
    if (socket == null) {
      print('Connection failed');
      return;
    }
    
    socket.writeFromSync('GET / HTTP/1.1\r\n\r\n'.codeUnits);
    
    var buffer = List.filled(1024, 0);
    socket.readIntoSync(buffer, 0, buffer.length);
    
    socket.closeSync();
  } on SocketException catch (e) {
    print('Socket error: ${e.message}');
  } catch (e) {
    print('Error: $e');
  }
}

我们将套接字操作包装在 try-catch 块中以处理潜在错误。SocketException 特别会捕获与网络相关的错误。务必进行清理。

$ dart main.dart
Socket error: Failed host lookup: 'invalid.host'

最佳实践

来源

Dart RawSynchronousSocket 文档

本教程通过实际示例介绍了 Dart 的 RawSynchronousSocket 类,演示了同步模式下的连接、读取、写入和错误处理。

作者

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

列出 所有 Dart 教程