UDP File Transfer Using Delphi Indy 10
我正在使用 Delphi Xe-3 indy 10 进行 udp 文件传输。我以小块的形式传递文件,在传输更大的文件和文本文件以外的文件时遇到问题。
在客户端调试时文件的大小保存错误,我无法找出原因。下面是客户端和服务器代码,客户端发送文件到服务器。
(我使用 udp 是因为我正在研究 Reliable udp。)
客户端代码(发送函数)中提到了问题。
服务器:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
procedure TForm2.serverUDPRead(AThread: TIdUDPListenerThread;
AData: array of Byte; ABinding: TIdSocketHandle); var str , len :string; begin setlength(b,length(Adata)); index:=0; save.Visible:= true; end; procedure TForm2.SaveClick(Sender: TObject); savedialog1.FileName := Ext; // save file name Strm:=TFileStream.Create(Ext,fmCreate); end; |
客户:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
procedure TForm1.LoadClick(Sender: TObject);
begin //openDialog1.InitialDir := GetCurrentDir; if openDialog1.Execute then begin Filename := ExtractFileName (Opendialog1.FileName); end; {finally end; procedure TForm1.SendClick(Sender: TObject); size := length(chunk) + length(Filename)*2 + 2; // it gets right sizes here , client.SendBuffer(‘127.0.0.1’,6002,File_data); finally end; procedure TForm1.FormCreate(Sender: TObject); end. |
- 如果您没有充分的理由使用 UDP,那么您应该几乎总是使用 TCP。不保证接收 UDP 数据包,并且不以任何特定顺序接收。
- 我说我正在努力构建可靠的 udp 协议。这是我需要做的一个项目。
- 如果你想构建一个可靠的 UDP 协议,你将不得不做更多的工作。第一个问题是数据包排序。 TCP 保证首先传送数据包 1,而 UDP 不保证。 UDP 确实会重新传输pacekts 等等……您在此处显示的代码根本不可靠。也许您需要在尝试编写任何代码之前先研究”可靠的 UDP”?
- 不,我这样做是为了聊天。现在我正在通过那个寻找文件传输..所以尝试了文件传输代码示例。
- 但是 Rudp 是为了可靠性,而不是为了将文件分解成块,或者我应该在 Rudp 中实现那个东西吗?
- 是的,我以前听说过那个东西(对文件传输不太了解)但是从零开始的文件流没有告诉他们开始位置吗?它以与源文件相同的模式复制(直到为我复制的级别)。
- 我只是想知道我提到的问题是 udp 的错误还是正常行为?
- 您的客户端代码以块的形式发送文件数据,而没有确定哪些块按什么顺序排列。请记住,UDP 不保证这些块将按照它们被发送的相同顺序传送,也不保证它们将被传送。这就是为什么我建议您改用 TFTP 协议的原因,因为它确实保证了排序,并且允许在丢失的卡盘丢失时重新传输它们。
- 此外,您的服务器代码仅在按下按钮时才保存块,但在您按下按钮之前或在保存对话框仍然可见时可能会到达多个块。您需要将每个块保存在 OnUDPRead 事件中(每个块到达时触发),因此您需要在接收第一个块之前提示输入目标文件,而不是在接收块的中间。更有理由切换到 TFTP 协议。
- TFTP 发送文件名并提示接收者允许继续,然后再发送第一个块。接收者可以在返回初始回复之前创建文件,然后在它们到达时将块接收到该文件中。 Indy 的 TFTP 组件会为您处理这些细节。
- @RemyLebeau:非常感谢您的帮助,在开始使用 tidtrivialftpserver 之前,我想问一下它的服务器组件是否像 tidudpserver 一样作为客户端和服务器工作?因为我需要为 p2p 而不是客户端/服务器实现它。
- 您不能将 TIdTrivialFTPServer 用作客户端,只能用作服务器。您必须使用 TIdTrivialFTP 作为客户端。
- 好的,我认为对于 p2p,我必须将两个组件放在一个表单上?以便它可以同时作为客户端或服务器(发送和接收)做出反应。对吗?
Indy 有 TIdTrivialFTP 和 TIdTrivialFTPServer 组件。 TFTP 是一种基于 UDP 的文件传输协议。您应该考虑使用它而不是创建自己的自定义协议。
来源:https://www.codenong.com/19763125/