如何确定套接字缓冲区中是否收到所有数据?

时间:2012-12-02 18:59:16

标签: delphi sockets

是否可以确定TServerSocket 接收缓冲区是否包含其中的所有数据?

3 个答案:

答案 0 :(得分:6)

协议的情况就是如此。

  • 可以是已定义的结束令牌。例如HTTP中的CR LF CR LF
  • 包含请求长度的标头。

答案 1 :(得分:5)

无法确定OnRead是否已完成阅读,因为根据定义,没有结束。这意味着您不应该在没有特殊信息的情况下发送二进制数据。例如,您可以首先发送字节数(例如,比如4字节无符号整数),然后发送您希望发送的字节数。

在接收方,你会先读取4个字节,现在你知道可以预期的字节数。

答案 2 :(得分:0)

如果您打算从服务器上的客户端读取数据,这是使用缓冲区字符串(每个客户端套接字)和解析该字符串的循环的典型方法。例如,我假设您创建一个对象来包装每个服务器/客户端套接字。在此对象中,创建一个名为Buffer的字符串。每当您从客户端接收数据时,请将新数据附加到此字符串的末尾。然后,一个单独的进程(一个线程)可以解析该字符串并检查完整的数据包。然而,读取数据包大小的方法完全取决于您。

无法保证服务器在按照发送顺序接收数据时会触发事件。客户端可以向服务器发送4个数据包,并且服务器仅针对所有数据包触发一个事件,或者客户端可以发送1个数据包,并且服务器针对该数据的一部分触发两个事件。根据套接字通信的性质,您有责任不断读取完整性数据。

alzaimar的答案就是你需要做的。假设一个完整的数据包是这样的字符串:

This is some string.

在解析这样的字符串时,使用分隔符是有风险的。因此,请使用该字符串的大小并在数据包上添加前缀,只需在该大小和数据之间使用一个分隔符。由于上面的字符串长度为20个字符,因此实际数据包应如下所示:

20:This is some string.

...冒号(:)是大小和数据之间的分隔符。首先,检查以确保存在分隔符。如果是这样,那么将所有内容复制到它。如果它是有效数字,则表示您需要从缓冲区中读取许多字符。接下来,检查缓冲区是否有可用的数据。如果是这样,那么从缓冲区中获取数据。请记住,只在必要时才从缓冲区中删除数据 - 如果您愿意,我可以提供更详细的代码示例。