FileZillaIt is a fast and reliable FTP client and server-side open source code program with a variety of features and intuitive interfaces. This article analyzes the source code of FileZilla.
I have analyzed the process of FTP client login to the server. Now let's take a look at the common ls command processing process.
After the user inputs the lscommand on the ftpclient, ftp.exe first sends a port request to the server and is processed in the ParseCommand () of CControlSocket.
The PORT command parameters are in the form of 127.0.0.1.4.9. The first four are the Client IP addresses, and the last two are based on Rule 4*256 + 9 = 1033, indicates the port temporarily established by the FTP client to establish a data connection with the server, as shown in the example of port 1033.
The preceding code in the processing process of the port command is used to obtain the IP address and temporary PORT:
Case COMMAND_PORT:
...
Port + = 256 * _ ttoi (args. Right (args. GetLength ()-(I + 1); // add MS byte to server socket
Ip = args. Left (I );
...
Below:
M_transferstatus.ip = ip;
M_transferstatus.port = port;
M_transferstatus.pasv = 0;
Send (_ T ("200 Port command successful "));
Break;
Just record the temporary Port provided by the FTP client to m_transferstatus, and then issue the 200 Port command successful, waiting for the next command of the FTP client. After the user inputs the lscommand, ftp.exe issues The NLST command after the PORT.
In case COMMAND_NLST processing, a series of parameter and permission checks are performed first. After everything is OK:
If (! M_transferstatus.pasv) // Active Mode
{
...
}
Else // Passive Mode
{
...
}
Because the active mode is the default value, let's take a look at the Code:
CTransferSocket * transfersocket = new CTransferSocket (this );
M_transferstatus.socket = transfersocket;
Transfersocket-> Init (pResult, TRANSFERMODE_NLST); // only initialize some parameters.
If (m_transferMode = mode_zlib) // whether the transmission mode uses the compression mode. It is not used by default. For details, see FTP specifications.
{
If (! Transfersocket-> InitZLib (m_zlibLevel ))
{
Send (_ T ("550 cocould not initialize zlib, please use mode s instead "));
ResetTransferstatus ();
Break;
}
}
If (! CreateTransferSocket (transfersocket) // create a data connection
Break;
SendTransferinfoNotification (TRANSFERMODE_LIST, physicalDir, logicalDir); // Use TRANSFERMODE_LIST instead of TRANSFERMODE_NLST.
Send (_ T ("150 Opening data channel for directory list ."));
Let's take a look at the code for establishing a data connection:
BOOL CControlSocket: CreateTransferSocket (CTransferSocket * pTransferSocket)
{
...
If (pTransferSocket-> Connect (m_transferstatus.ip, m_transferstatus.port) = 0)
...
}
It is nothing more than a conventional socket method to establish a connection. It is important to note that the Service initiates a connection actively, which is exactly what the Active Mode means. Let's take a look at the passive mode.
After CreateTransferSocket () is complete, call:
SendTransferinfoNotification (TRANSFERMODE_LIST, physicalDir, logicalDir );
Let's take a look:
Void CControlSocket: SendTransferinfoNotification (const char transfermode, const CStdString & physicalFile, const CStdString & logicalFile, _ int64 startOffset, _ int64 totalSize)
{
T_connop * op = new t_connop;
Op-> op = USERCONTROL_CONNOP_TRANSFERINIT;
Op-> userid = m_userid;
T_connectiondata_transferinfo * conndata = new t_connectiondata_transferinfo;
Conndata-> transferMode = transfermode;
Conndata-> physicalFile = physicalFile;
Conndata-> logicalFile = logicalFile;
Conndata-> startOffset = startOffset;
Conndata-> totalSize = totalSize;
Op-> data = conndata;
M_pOwner-> SendNotification (FSM_CONNECTIONDATA, (LPARAM) op );
}
You can see that a message is sent to the CServer. The wParam parameter is FSM_CONNECTIONDATA, indicating that this is a connection-related message. The lParam parameter is USERCONTROL_CONNOP_TRANSFERINIT, indicating that the transmission starts or ends, I will go back and take a look at the OnServerMessage () code in CServer. The information that will be transmitted is displayed below the admin window.
Below,
Send (_ T ("150 Opening data channel for directory list ."));
The message sent to the FTP client for data connection creation. The real data transmission task is handed over to the data connection, that is, CTransferSocket.
We return to the passive mode. If the passive mode is used:
If (! M_transferstatus.pasv)
{
...
}
Else // Passive Mode
{
...
M_transferstatus.socket-> PasvTransfer ();
}
Let's take a look at the implementation of PasvTransfer:
Void CTransferSocket: PasvTransfer ()
{
If (bAccepted)
If (! M_bStarted)
InitTransfer (FALSE );
}
It is very simple. Because it is a passive mode, that is, the client initiates a data connection, so CTransferSocket only needs to wait for the connection from the client. The following describes the implementation of CTransferSocket.
Through the complete description in this article, you should know the source code of FileZilla and hope to help you!
- FileZilla source code analysis 1
- FileZilla source code analysis 2
- FileZilla source code analysis 3
- FileZilla source code analysis 4
- FileZilla source code analysis 5
- FileZilla source code analysis 6
- FileZilla source code analysis 7
- FileZilla source code analysis 8
- FileZilla source code analysis 9