使用winsock进行文件传输

时间:2010-12-01 16:51:30

标签: delphi winsock

我希望通过winsock发送文件(文本或二进制文件),我有一个32768字节大小的缓冲区,另一方面缓冲区大小相同,但是当数据包大小<32768时我不喜欢我不知道如何确定缓冲区中数据包的结束,另外用二进制文件似乎标记数据包的结尾具有唯一字符是不可能的,有什么解决方案吗? THX

2 个答案:

答案 0 :(得分:1)

嗯,您始终可以在开始文件传输之前发送文件大小,这样您就可以知道何时停止写入文件。

答案 1 :(得分:1)

对于固定大小的“数据包”,我们通常会认为除了最后一个数据包之外的每个数据包都将完全充满有效数据。只有最后一个将是“部分”,如果收件人知道要预期多少字节(因为,使用Davita的建议,发件人提前告诉它文件大小),那就没问题了。收件人可以简单地忽略最后一个数据包的剩余部分。

但是你的进一步描述听起来似乎可能有多个部分完整的数据包与单个文件传输相关联。有一个类似的简单解决方案:使用有效字节数为每个数据包添加前缀。

你后来提到TCustomWinSocket.ReceiveText,你想知道它是如何知道要读取多少文本,然后你引用答案,即它调用ReceiveBuf(Pointer(nul)^, -1))来设置结果缓冲区的长度之前填补它。也许你只是不明白那段代码在做什么。如果您在另一个上下文ReceiveLength方法中查看相同的代码,则更容易理解。它对ReceiveBuf进行相同的调用,表示当你将-1传递给ReceiveBuf时,它会返回它收到的字节数。

为了使其能够满足您的需要,您无法发送固定大小的数据包。如果你总是发送32KB数据包,并且只用零填充结尾,那么ReceiveLength将始终返回32768,你必须将Davita和我的解决方案结合起来发送文件和数据包长度以及有效负载。但是,如果您确保数据包中的每个字节始终有效,则收件人可以根据数据包的大小知道要保存多少。

无论如何,您需要确保发件人向收件人提供完成工作所需的信息。如果发件人发送垃圾而没有让收件人将垃圾与有效数据区分开来,那么你就会陷入困境。