使用winsock进行文件传输
我想通过 winsock
发送文件(文本或二进制),我有一个 32768 字节大小的缓冲区,在另一侧缓冲区大小相同,但是当数据包大小 <32768 时我不这样做不知道如何确定缓冲区中数据包的结尾,而且对于二进制文件,似乎不可能用唯一字符标记数据包的结尾,有什么解决方案吗? 谢谢
I want to send files(text or binary) through winsock
,I have a buffer with 32768 byte size, In the other side the buffer size is same,But when the packet size <32768 then i don't know how determine the end of packet in buffer,Also with binary file it seems mark the end of packet with a unique character is not possible,Any solution there?
thx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于固定大小的“数据包”,我们通常会认为除了最后一个数据包之外的每个数据包都将完全充满有效数据。只有最后一个是“部分的”,如果接收者知道需要多少字节(因为,根据 Davita 的建议,发送者提前告诉它文件大小),那么就没有问题。接收者可以简单地忽略最后一个数据包的其余部分。
但您的进一步描述听起来可能有多个部分完整的数据包与单个文件传输相关。有一个类似简单的解决方案:在每个数据包前面加上有效字节数的前缀。
您稍后提到
TCustomWinSocket.ReceiveText
,您想知道它如何知道要读取多少文本,然后您引用答案,即它调用ReceiveBuf(Pointer(nul)^, - 1))
在填充结果缓冲区之前设置其长度。也许您只是不明白该代码的作用。如果您在另一个上下文中查看相同的代码(ReceiveLength
方法),就会更容易理解。它对 ReceiveBuf 进行相同的调用,表明当您将 -1 传递给 ReceiveBuf 时,它会返回收到的字节数。为了使其能够满足您的目的,您不能发送固定大小的数据包。如果您始终发送 32KB 数据包,并且仅在末尾填充零,则 ReceiveLength 将始终返回 32768,并且您必须将 Davita 和我的解决方案结合起来,发送文件和数据包长度以及有效负载。但是,如果您确保数据包中的每个字节始终有效,那么接收者就可以根据数据包的大小知道要保存多少字节。
无论怎样,您需要确保发件人向收件人提供完成其工作所需的信息。如果发送者发送垃圾而没有给接收者提供区分垃圾和有效数据的方法,那么你就会陷入困境。
With fixed-size "packets," we would usually that every packet except the last will be completely full of valid data. Only the last one will be "partial," and if the recipient knows how many bytes to expect (because, using Davita's suggestion, the sender told it the file size in advance), then that's no problem. The recipient can simply ignore the remainder of the last packet.
But your further description makes it sound like there may be multiple partially full packets associated with a single file transmission. There is a similarly easy solution to that: Prefix each packet with the number of valid bytes.
You later mention
TCustomWinSocket.ReceiveText
, and you wonder how it knows how much text to read, and then you quote the answer, which is that it callsReceiveBuf(Pointer(nul)^, -1))
to set the length of the result buffer before filling it. Perhaps you just didn't understand what that code is doing. It's easier to understand if you look at that same code in another context, theReceiveLength
method. It makes that same call toReceiveBuf
, indicating that when you pass -1 toReceiveBuf
, it returns the number of bytes it received.In order for that to work for your purposes, you cannot send fixed-size packets. If you always send 32KB packets, and just pad the end with zeroes, then
ReceiveLength
will always return 32768, and you'll have to combine Davita's and my solutions of sending file and packet lengths along with the payload. But if you ensure that every byte in your packet is always valid, then the recipient can know how much to save based on the size of the packet.One way or another, you need to make sure the sender provides the recipient with the information it needs to do its job. If the sender sends garbage without giving the recipient a way to distinguish garbage from valid data, then you're stuck.
那么,您始终可以在开始文件传输之前发送文件大小,这样您就知道何时停止写入文件。
Well, you can always send file size before you start file transfer, so you'll know when to stop writing to file.