Kitura / BlueSocket

Socket framework for Swift using the Swift Package Manager. Works on iOS, macOS, and Linux.
Apache License 2.0
1.41k stars 197 forks source link

Download multiple files #200

Closed Nathipha closed 3 years ago

Nathipha commented 3 years ago

I want to download multiple files from an FTP server. The first file downloads successfully but the second,... one always fails.

FTP commands:

Login + connect cmdSocket
cmdSocket send: PASV
cmdSocket receive: 227 Entering Passive Mode
cmdSocket send: TYPE I
cmdSocket receive: 200 Type set to I
Connect dataSocket to Passive Mode IP/port
cmdSocket send: CWD myFolder
cmdSocket receive: 250 CWD command successful

Looping through all the files:

cmdSocket send: RETR myFileX
cmdSocket receive: Either "150 Downloading in BINARY file" or "125 Data connection already open; Transfer starting"
dataSocket: Receive data with "read(into data: inout Data)" write it to the "Documents" folder
cmdSocket receive: 226 Transfer complete

This works fine for the first file ("myFile1") but everything changes in the second loop iteration ("myFile2"):

cmdSocket send: RETR myFile2
cmdSocket receive: 150 Opening BINARY mode data connection.

Now the dataSocket won't return any bytes (myData.count is 0) and sometimes it also receives "425 Cannot open data connection." in addition to "150". I tried to use "myFile1" twice but with the same result.

I'm guessing that the order is off but what is wrong exactly? Do I have to change the type for every file, so within the loop? Do I have to open a new data socket for every file or maybe send some "reset" command after "226" is received for the first file?

Nathipha commented 3 years ago

Found the problem: In "stream" mode (which is the default setting afaik) a data socket can only be used for a single e.g. RETR. Afterwards it sends 226 and closes itself. dataSocket.isConnected then still returns true but another RETR only returns 0 bytes, use dataSocket.remoteConnectionClosed instead to check.

To download multiple files open a new data socket with a new passive connection for every file:

Login + connect cmdSocket
cmdSocket send: CWD myFolder
cmdSocket receive: 250 CWD command successful
cmdSocket send: TYPE I
cmdSocket receive: 200 Type set to I
Loop through all the files
cmdSocket send: PASV
cmdSocket receive: 227 Entering Passive Mode
Connect dataSocket to Passive Mode IP/port
cmdSocket send: RETR myFileX
cmdSocket receive: Either "150 Downloading in BINARY file" or "125 Data connection already open; Transfer starting"
dataSocket: Receive data with "read(into data: inout Data)" & write it to the "Documents" folder
cmdSocket receive: 226 Transfer complete
Close the dataSocket (not sure if still necessary)
dannys42 commented 3 years ago

@Nathipha Thanks for updating with your resolution.