乐趣区

dart-socket-error错误一览

SocketException: OS Error: Broken pipe, errno = 32

这个错误其实有点迷惑性,很多时候调用栈显示是在 socket.connect 的时机出的错,但实际是因为 socket 已经被对端关闭,而关闭的原因可能是因为发送了错误的数据。

解决:
发送数据时机检查 socket 连接状态及数据正确性。

Bad state: StreamSink is bound to a stream

这个错误容易发生在调用 socket.flush 之后,这是因为 flush 操作是一个 future, 如果在这个操作结束之前就向 socket 中写入数据就会报这个错误。实际上调用 socket.close 也有可能遇到这种错误。在 io_sink.dart 里源码如下:

  Future flush() {if (_isBound) {throw new StateError("StreamSink is bound to a stream");
    }
    ...
  }

  Future close() {if (_isBound) {throw new StateError("StreamSink is bound to a stream");
    }
    ...
    return done;
  }

解决:
或者写入时机在 flush 完成之后,需要外部关心写入时机;或者封装 socket 并持有一个缓冲数据对象,外部写入时判断当前 socket 状态,如果 flush 完成则直接 socket.add 否则写入到缓冲区,flush 完成时再发送缓冲的数据,外部就不用再关心写入时机了。

后者实现显然更复杂,需要一揽子的状态判断和处理操作,但是把这个复杂留给外部逻辑会让工程整体更复杂。

StreamSink is closed

这个错误虽然直白但需要明确什么时机哪个 stream 是关闭的。一种情况是发生在和 socket 进行关联的 stream 的关闭操作上,如上 socket.close 是一个 future, future 结束之前还能够接收数据,如果我们的关联 stream 的 close 是和 socket.close 一个时机,那么当 socket.close 的 future 还没有结束这时又有数据从远端过来,调用关联 stream 的处理操作就会出这个错误。
形如:

void close() {_socket.close();
  your_stream.close();}

void handleData() {_socket.listen((data) {your_stream.add(yourData(data)); // your_stream 可能已经关闭
  });
}

解决:
关联的 stream 的操作应当在 socket.close 的 future 结束之后再关闭。
形如:

void close() async {await _socket.close();
  your_stream.close();}
退出移动版