在将遥控器设置为读取丢弃字节之前,是否将字节写入TcpClient的NetworkStream?

时间:2019-05-06 22:45:13

标签: c# sockets tcp

我正在设置一些套接字,遇到一些奇怪的行为,想知道是否可以预期。

我在插槽的每一侧都有两个线程。编写器(每侧一个)仅从队列中获取消息,对其进行序列化,然后写入字节。读取器(每侧一个)读取我的自定义协议的标头和正文,反序列化消息并引发事件。

足够简单,对吧?

当客户端连接到服务器然后立即写入消息时,会发生我感兴趣的奇怪行为。客户端的速度可能如此之快,以至于在客户端发送消息时服务器尚未启动其读取线程。如果发生这种情况,则服务器将永远不会收到该消息。在读取线程实际调用Read()之后发送的消息已成功接收和处理。

这是预期的行为吗?是否期望在读取另一端之前写入套接字的字节会被Read()忽略?

1 个答案:

答案 0 :(得分:1)

否,TCP接收缓冲区是在三向握手期间创建的,第一次读取将看到到目前为止连接上已发送的所有数据。

这是假设您具有有效的TCP / IP实现。如果连接的另一端是嵌入式设备上的最小手动旋转TCP库,则所有选择都将关闭。

更有可能的是,一次阅读会收到几封邮件,而收件人却忘记了处理超过第一封邮件的任何内容。 TCP不保留消息边界。您必须在协议中包括足够的长度和/或定界信息才能恢复这些边界。而且,您必须处理在读取缓冲区中收到少于或多于一条消息的情况。