关于socket编程文件传输的问题
有没有一种好的方法可以将文件从客户端传输到服务器? 可能只是图像,但我的教授要求提供任何类型的文件。
我环顾四周,对总体思路有点困惑。
因此,如果我们有一个大文件,我们可以将该文件分割成多个段......?然后将每个片段发送到服务器。
我还应该使用 while 循环来接收服务器端的所有文件/段吗?另外,我的服务器如何知道是否已收到所有段而不事先知道有多少段?
我在 Cplusplus 网站上查找,发现有类似文件的二进制传输...
感谢所有帮助 =)
Is there a good method on how to transfer a file from say... a client to a server?
Probably just images, but my professor was asking for any type of files.
I've looked around and am a little confused as to the general idea.
So if we have a large file, we can split that file into segments...? Then send each segment off to the server.
Should I also use a while loop to receive all the files / segments on the server side? Also, how will my server know if all the segments were received without previously knowing how many segments there are?
I was looking on the Cplusplus website and found that there is like a binary transfer of files...
Thanks for all the help =)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您使用 TCP:
您是对的,没有办法“知道”您将接收多少数据。这为您提供了一些选择:
1) 在传输图像数据之前,首先发送预期的字节数。所以你的前 4 个字节可能是 4 字节整数“4096”。然后,您的客户端可以读取前 4 个字节,“知道”它需要 4096 个字节,然后读取
malloc(4096)
,以便它可以期待其余的字节。然后,您的服务器可以 send() 4096 字节的图像数据。当您执行此操作时,请注意您可能必须多次调用 recv() - 由于某种原因,您可能没有收到全部 4096 字节。因此,您需要检查 recv() 的返回值以确保您已获得所有内容。
2) 如果您只发送一个文件,您可以让接收者读取它。并且它可以继续从套接字进行recv()操作,直到服务器关闭连接。这有点困难 - 你必须跟踪你收到了多少,然后如果你的缓冲区已满,你将不得不重新分配它。我不推荐这种方法,但它在技术上可以完成任务。
如果您使用 UDP:
这意味着您没有可靠的传输。因此数据包可能会被丢弃。它们也可能不按顺序到达。因此,如果您要使用 UDP,则必须将数据分段为小段。发送方和接收方都必须就数据段的大小达成一致(100 字节?1000 字节?)
不仅如此,还必须为每个数据包传输一个序列号 - 即为每个数据包标记 #1、#2、因为您的客户端必须能够判断:是否有任何数据包丢失(您收到数据包 1、2 和 4 - 因此丢失了 #3)并确保它们按顺序排列(您收到 3、2,然后是 1) - 但是当您将它们保存到文件时,您必须确保数据包以正确的顺序保存,1、2,然后3)。
因此,对于您的任务,这将取决于您必须/被允许使用什么协议。
If you are using TCP:
You are right, there is no way to "know" how much data you will be receiving. This gives you a few options:
1) Before transmitting the image data, first send the number of bytes to be expected. So your first 4 bytes might be the 4-byte integer "4096". Then your client can read the first 4 bytes, "know" that it is expecting 4096 bytes, and then
malloc(4096)
so it can expect the rest. Then, your server can send() 4096 bytes worth of image data.When you do this, be aware that you might have to recv() multiple times - for one reason or another, you might not have received all 4096 bytes. So you will need to check the return value of recv() to make sure you have gotten everything.
2) If you are just sending one file, you could just have your receiver read it. And it can keep recv()ing from the socket until the server closes the connection. This is a bit harder - you will have to keep track of how much you have received, and then if your buffer is full, you will have to reallocate it. I don't recommend this method, but it would technically accomplish the task.
If you are using UDP:
This means that you don't have reliable transfer. So packets might be dropped. They might also arrive out of order. So if you are going to use UDP, you must fragment your data into little segments. Both the sender and receiver must have agreement on how large a segment is (100 bytes? 1000 bytes?)
Not only that, but you must also transmit a sequence number with each packet - that is, label each packet #1, #2, etc. Because your client must be able to tell: if any packets are missing (you receive packets 1, 2 and 4 - and are thus missing #3) and to make sure they are in order (you receive 3, 2, then 1 - but when you save them to the file, you must make sure the packets are saved in the correct order, 1, 2, then 3).
So for your assignment, well, it will depend on what protocol you have to/are allowed to use.
如果您使用基于 UDP 的传输协议,则必须将文件分成块才能进行网络传输。您还必须在接收端以正确的顺序重新组装它们并验证结果。如果您使用基于 TCP 的传输协议,所有这些都将在幕后处理。
您应该查阅 Beej 网络编程指南,了解如何最好地发送和接收数据以及一般情况下使用套接字。它解释了您所询问的大部分事情。
If you use a UDP-based transfer protocol, you will have to break the file up into chunks for network transmission. You'll also have to reassemble them in the correct order on the receiving end and verify the results. If you use a TCP-based transfer protocol, all of this will be taken care of under the hood.
You should consult Beej's Guide to Network Programming for how best to send and receive data and use sockets in general. It explains most of the things about which you are asking.
传输文件的方法有很多种。如果您以无损方式传输文件,那么您基本上会将文件分成块。用序列号标记每个块。将块发送到另一端并重建文件。面向流的协议更简单,因为如果丢失数据包将重新传输。如果您使用不可靠的协议,那么您将需要重新传输丢失的数据包和重新排序的数据块,这些数据块的顺序不正确。
如果有损传输是可以接受的(例如传输视频或在线游戏数据),则使用不可靠的协议。有损传输更简单,因为您不必重新传输丢失的块。您需要做的就是确保按正确的顺序处理块。
许多协议发送终止符数据包来指示传输结束。如果您不想在传输之前将块的数量发送到另一方,则可以使用此策略。
There are many ways of transferring files. If your transferring files in a lossless manor, then your basically going to divide the file into chunks. Tag each chunk with a sequence number. Send the chunks to the other side and reconstitute the file. Stream oriented protocols are simpler since packets will be retransmitted if lost. If your using an unreliable protocol, then you will need to retransmit missing packets and resequenced chunks which are not in the correct order.
If lossy transfer is acceptable (like transferring video or on-line game data), then use an unreliable protocol. Lossy transfer is simpler because you don't have to retransmit missing chunks. All you need to do is make sure the chunks are processed in the proper sequence.
Many protocols send a terminator packet to indicate the end of transmission. You could use this strategy if you don't want to send the number of chunks to the other side before transmission.