March 16, 2011
FTP GetData discrepancy
There’s a problem with the logic of FTP.GetData. FTP protocol specifies, that when downloading a file, the DATA connection is established and when the download is complete it is closed.
On socket level (OS level, not lNet), recv() syscall will return 0 when a connection gets closed at the sender. This would normally indicate to us that the FTP file transfer is complete. However, lNet’s sockets return 0 also on “non-errors”.
Non-errors are situations in which the recv() call returns -1, and the error tells lNet that “I would receive some data, but my OS buffer is full, please wait a bit”. lNet handles this internally, and returns 0 on the TLSocket.Get. This is a bit of a problem because in FTP this is returned on GetData and thus a false “file complete” message is sent.
The only proper solution to this problem is reworking of this logic so that GetData returns when the transfer is complete in an exact way. This means that next lNet release a logical change will take place in the FTP client component which might break existing code :(.
It’s missed things like these which make me most sad, because it’s a small problem, but it an have big impact. Until 0.6.6 (or even 0.7.x possibly) is released, the trunk lNet has a workaround in the FTP examples. People who use FTP atm. and have this problem need to check if the file they’re downloading is complete (compare expected size to received size) before closing it and changing state to “file downloaded”, even if FTP.GetData returns 0.
I’m not yet sure how the new GetData will behave. It might be an API change (so old code breaks, and people won’t get silent bugs) for example with a new argument which will tell if the transaction is completed.