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.
<Type = "text/javascript"> <src = "http://pagead2.googlesyndication.com/pagead/show_ads.js" type = "text/javascript"> <type = "text/javascript"> <src = "http://pagead2.googlesyndication.com/pagead/show_ads.js" type = "text/javascript">
In Create () of CServer, Create the CListenSocket object to listen to port 21 to see the specific code implementation:
CListenSocket * pListenSocket = new CListenSocket (this, ssl );
If (! PListenSocket-> Create (nPort, SOCK_STREAM, FD_ACCEPT, NULL) |! PListenSocket-> Listen ())
There are basically three steps:
1. new CListenSocket: Nothing special. Basically, it is to initialize the member variable.
2. Create
Note: In all the code, do not read a lot of if (m_pFirstLayer) code, which is the mechanism of CAsyncSocketExLayer.
Create actually calls the create () method of the parent class CAsyncSocketEx. The first thing in this method is to establish the relationship between the consumer chain, distribution thread t_AsyncSocketExThreadData, and CAsyncSocketEx. create () of CAsyncSocketEx () the method first calls InitAsyncSocketExInstance (). The following is the sample code of CAsyncSocketEx: InitAsyncSocketExInstance:
DWORD id = GetCurrentThreadId ();
...
// Get thread specific data
If (m_spAsyncSocketExThreadDataList) // This chain has been created
{
T_AsyncSocketExThreadDataList * pList = m_spAsyncSocketExThreadDataList;
While (pList) // Traversal
{
ASSERT (pList-> pThreadData );
ASSERT (pList-> pThreadData-> nInstanceCount> 0 );
If (pList-> pThreadData-> nThreadId = id) // if a distribution thread already exists for the current thread, the distribution of the current socket is represented by this distribution thread.
{
M_pLocalAsyncSocketExThreadData = pList-> pThreadData;
M_pLocalAsyncSocketExThreadData-> nInstanceCount ++; // This socket is added.
Break;
}
PList = pList-> pNext;
}
// Current thread yet has no sockets
If (! PList) // if the current thread does not have a distribution thread, create
{
// Initialize data for current thread
PList = new t_AsyncSocketExThreadDataList;
PList-> pNext = m_spAsyncSocketExThreadDataList;
M_spAsyncSocketExThreadDataList = pList;
M_pLocalAsyncSocketExThreadData = new t_AsyncSocketExThreadData;
M_pLocalAsyncSocketExThreadData-> nInstanceCount = 1; // only the current socket is mounted
M_pLocalAsyncSocketExThreadData-> nThreadId = id; // threadID of the distribution thread
M_pLocalAsyncSocketExThreadData-> m_pHelperWindow = new CAsyncSocketExHelperWindow (m_pLocalAsyncSocketExThreadData); // create CAsyncSocketExHelperWindow for this distribution thread
M_spAsyncSocketExThreadDataList-> pThreadData = m_pLocalAsyncSocketExThreadData;
}
}
Else // if the distribution thread chain has not been created, create
{// No thread has instances of CAsyncSocketEx; Initialize data
M_spAsyncSocketExThreadDataList = new t_AsyncSocketExThreadDataList;
M_spAsyncSocketExThreadDataList-> pNext = 0;
M_pLocalAsyncSocketExThreadData = new t_AsyncSocketExThreadData; // the first distribution thread
M_pLocalAsyncSocketExThreadData-> nInstanceCount = 1; // only the current socket is mounted
M_pLocalAsyncSocketExThreadData-> nThreadId = id; // threadID of the distribution thread
M_pLocalAsyncSocketExThreadData-> m_pHelperWindow = new CAsyncSocketExHelperWindow (m_pLocalAsyncSocketExThreadData); // create CAsyncSocketExHelperWindow for this distribution thread
M_spAsyncSocketExThreadDataList-> pThreadData = m_pLocalAsyncSocketExThreadData;
...
}
The following describes how to create a CAsyncSocketExHelperWindow:
CAsyncSocketExHelperWindow (CAsyncSocketEx: t_AsyncSocketExThreadData * pThreadData)
{
// M_pAsyncSocketExWindowData is an array of t_AsyncSocketExWindowData,
// Each element of the array represents a CAsyncSocketEx, that is, the socket to be served
// Initialize data
M_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData [512]; // Reserve space for 512 active sockets
Memset (m_pAsyncSocketExWindowData, 0,512 * sizeof (t_AsyncSocketExWindowData ));
M_nWindowDataSize = 512; // the size of the current array, which can be expanded automatically, but the maximum value cannot exceed one
M_nSocketCount = 0; // Number of CAsyncSocketEx instances in the current array
M_nWindowDataPos = 0; // to add a new CAsyncSocketEx to the position of the array
M_pThreadData = pThreadData; // distribution thread corresponding to CAsyncSocketExHelperWindow.
// Create a standard window below, but it is not displayed
// Create window
WNDCLASSEX wndclass;
Wndclass. cbSize = sizeof wndclass;
Wndclass. style = 0;
Wndclass. lpfnWndProc = WindowProc;
Wndclass. cbClsExtra = 0;
Wndclass. cbWndExtra = 0;
Wndclass. hInstance = GetModuleHandle (0 );
Wndclass. hIcon = 0;
Wndclass. hCursor = 0;
Wndclass. hbrBackground = 0;
Wndclass. lpszMenuName = 0;
Wndclass. lpszClassName = _ T ("CAsyncSocketEx Helper Window ");
Wndclass. hIconSm = 0;
RegisterClassEx (& wndclass );
M_hWnd = CreateWindow (_ T ("CAsyncSocketEx Helper Window"), _ T ("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, getModuleHandle (0 ));
ASSERT (m_hWnd );
SetWindowLongPtr (m_hWnd, GWL_USERDATA, (LONG) this );
};
After InitAsyncSocketExInstance () is called, The create () method of CAsyncSocketEx is then:
SOCKET hSocket = socket (m_SocketData.nFamily, nSocketType, 0); // This is the real socket api, create a socket
If (hSocket = INVALID_SOCKET)
Return FALSE;
M_SocketData.hSocket = hSocket;
AttachHandle (hSocket); // Add the currently created socket to the distribution thread management. This allows the distribution thread to take charge of the socket message.
AttachHandle () calls the AddSocket method of CAsyncSocketExHelperWindow:
BOOL AddSocket (CAsyncSocketEx * pSocket, int & nSocketIndex)
{
...
// Search for free slot
// Start searching from m_nWindowDataPos and search m_nWindowDataSize locations
// Since it is the following modulo operation I % m_nWindowDataSize, when it reaches the end of the array, it starts from re-winding back, that is, each position of the array is received
For (int I = m_nWindowDataPos; I <(m_nWindowDataSize + m_nWindowDataPos); I ++)
{
// Note the modulo operation
If (! M_pAsyncSocketExWindowData [I % m_nWindowDataSize]. m_pSocket) // The location is empty.
{
M_pAsyncSocketExWindowData [I % m_nWindowDataSize]. m_pSocket = pSocket;
NSocketIndex = I % m_nWindowDataSize; // pos in the list
M_nWindowDataPos = (I + 1) % m_nWindowDataSize; // the server will be available from the next search location.
M_nSocketCount ++;
Return TRUE;
}
}
...
}
In the socket array managed by CAsyncSocketExHelperWindow, add this CAsyncSocketEx.
The create () method of CAsyncSocketEx is then:
If (! AsyncSelect (lEvent ))
{
Close ();
Return FALSE;
}
Here, the AsyncSelect () method calls the windows socket api: WSAAsyncSelect (). This method enables windows to access the socket specified by CAsyncSocketEx. When the socket event accept, read, and write occurs, send the message to the window hWnd in CAsyncSocketExHelperWindow, and then CAsyncSocketExHelperWindow sends the message back to CAsyncSocketEx, which is responsible for processing the message through the callback function WindowProc (this part is analyzed in detail below ).
Continue the create () method of CAsyncSocketEx:
If (! Bind (nSocketPort, lpszSocketAddress ))
{
Close ();
Return FALSE;
}
Bind () actually calls the socket api: bind () method to Bind the local address and socket.
3. Listen
After the create operation is completed, it is the listen, which is relatively simple. It directly calls the socket api: listen () and listens on the specified address and port.
The program runs here, and the core class has been initialized. The following analyzes how messages are distributed from CAsyncSocketExHelperWindo to CAsyncSocketEx when the socket is active.
<Type = "text/javascript"> <src = "http://pagead2.googlesyndication.com/pagead/show_ads.js" type = "text/javascript">
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
- FileZilla: free server software
- New Version FileZilla 3.3.1.0 bug fixes