Transfer behavior
The lifecycle of one transfer
Follow a listing or file operation from data-endpoint selection through preliminary and completion replies.
One FTP transfer always follows the same shape. Pick active or passive mode, send get or put, read 150, move bytes on the data socket, then read the final reply on the control connection.
I walk new teammates through this sequence on a whiteboard before we touch firewall rules. If you know where you are in the list, you stop guessing random client settings.
Print the eight steps on a sticky note next to your monitor until they stick. I still skim them before a partner call.
Here is a download end to end:
ftp> epsv
229 Entering Extended Passive Mode (|||50010|)
ftp> get archive.tar.gz
150 Opening BINARY mode data connection
226 Transfer complete
150 means the server is opening the data path. 226 means the command finished successfully. You need both. A full file on disk without 226 is not proof of success.
Uploads mirror the same steps:
ftp> put notes.txt
150 Opening data connection
226 Transfer complete
Skipping the final reply hides quota errors and disk-full failures that happen after the data socket closes.
For downloads, I write to archive.tar.gz.part locally and rename after 226 and a size check. For uploads, I use the same idea on the server with a .part name.
If the data socket closes but 226 never arrives, the result is uncertain. Run ls on the server or check local file size before you retry. Blind retries with append can make things worse.
Listings follow the same lifecycle. mlsd still gets 150, bytes on the data channel, then 226 on the control connection.
Interrupt the example after 150 but before 226 on a test server. Note what files exist locally and remotely at that moment.
Lesson completed