是否可以确定TServerSocket
接收缓冲区是否包含所有数据?
3 回答
这就是协议的情况。
- 可以是定义的结束标记。例如 HTTP 中的 CR LF CR LF
- 包含请求长度的标头。
无法确定 OnRead 是否已完成读取,因为根据定义没有结束。这意味着您不应该简单地发送没有特殊信息的二进制数据。例如,您可以先发送字节数(例如,4 字节无符号整数),然后再发送您希望发送的字节数。
在接收方,您将首先读取 4 个字节,现在您知道可以预期多少字节。
如果您打算从服务器上的客户端读取数据,则使用缓冲区字符串(每个客户端套接字)和解析该字符串的循环是一种典型的方法。例如,我假设您创建一个对象来包装每个服务器/客户端套接字。在此对象中,创建一个名为Buffer
. 每当您从客户端接收数据时,将新数据附加到此字符串的末尾。然后,一个单独的进程(一个线程)可以解析这个字符串并检查一个完整的数据包。然而,读取数据包大小的方法完全取决于您。
不能保证服务器会按照发送的顺序在接收到数据时触发事件。客户端可能向服务器发送 4 个数据包,服务器只为所有数据触发一个事件,或者客户端可能发送 1 个数据包,服务器为部分数据触发两个事件。您有责任不断读取传入的数据以确保完整性,具体取决于套接字通信的性质。
alzaimar 的答案是你需要做的。假设一个完整的数据包是这样的字符串:
This is some string.
在解析这样的字符串时,使用分隔符是有风险的。因此,取而代之的是,取该字符串的大小并将其添加到您的数据包上,在该大小和数据之间仅使用一个分隔符。由于上面的字符串有 20 个字符长,实际的数据包应该是这样的:
20:This is some string.
...其中冒号 (:) 是大小和数据之间的分隔符。首先,您检查以确保分隔符存在。如果是这样,则将所有内容复制到它上面。如果它是一个有效数字,则意味着您需要从缓冲区中读取那么多字符。接下来,检查缓冲区是否有那么多可用数据。如果是这样,则从缓冲区中获取该数据。请记住仅在必要时从缓冲区中删除数据 - 如果您愿意,我可以提供更详细的代码示例。