FileZilla source code analysis 7

Source: Internet
Author: User
Tags filezilla

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.

After the service thread wakes up, it calls OnThreadMessage to process the WM_FILEZILLA_THREADMSG message. The parameter is FTM_NEWSOCKET and sockethandle. Then it enters the AddNewSocket method, indicating that a new client needs to be connected.

Void CServerThread: AddNewSocket (SOCKET sockethandle, bool ssl)

{

// Create a new CControlSocket class, which is also inherited from the CAsyncSocketEx class. After initialization, The CControlSocket class will take over the client connection.

CControlSocket * socket = new CControlSocket (this );

Socket-> Attach (sockethandle); // Add it to the FileZilla message mechanism to establish the relationship with the distribution thread.

CStdString ip;

Unsigned int port;

SOCKADDR_IN sockAddr;

Memset (& sockAddr, 0, sizeof (sockAddr ));

Int nSockAddrLen = sizeof (sockAddr );

BOOL bResult = socket-> GetPeerName (SOCKADDR *) & sockAddr, & nSockAddrLen); // obtain the information of the socket Client

If (bResult)

{

Port = ntohs (sockAddr. sin_port); // port

Ip = inet_ntoa (sockAddr. sin_addr); // ip address

}

Else

{

Socket-> m_RemoteIP = _ T ("ip unknown ");

Socket-> m_userid = 0;

Socket-> SendStatus (_ T ("Can't get remote IP, disconnected"), 1 );

Socket-> Close ();

Delete socket;

Return;

}

Socket-> m_RemoteIP = ip;

EnterCritSection (m_GlobalThreadsync );

Int userid = CalcUserID (); // automatically generates a customer ID for the current socket connection: userID

If (userid =-1)

{

LeaveCritSection (m_GlobalThreadsync );

Socket-> m_userid = 0;

Socket-> SendStatus (_ T ("Refusing connection, server too busy! "), 1 );

Socket-> Send (_ T ("421 Server too busy, closing connection. Please retry later! "));

Socket-> Close ();

Delete socket;

Return;

}

Socket-> m_userid = userid;

T_socketdata data;

Data. pSocket = socket;

Data. pThread = this;

M_userids [userid] = data; // m_userids is static and is defined as static std: map m_userids;

// You can ignore hammering.

// Check if remote IP is blocked due to hammering

Std: map: iterator iter = m_antiHammerInfo.find (sockAddr. sin_addr.s_addr );

If (iter! = M_antiHammerInfo.end ())

{

If (iter-> second> 10)

Socket-> AntiHammerIncrease (25 );//~ 6 secs delay

}

LeaveCritSection (m_GlobalThreadsync );

EnterCritSection (m_threadsync );

// Record the CControlSocket processed by this service thread

M_LocalUserIDs [userid] = socket;

LeaveCritSection (m_threadsync );

T_connectiondata_add * conndata = new t_connectiondata_add;

T_connop * op = new t_connop;

Op-> data = conndata;

Op-> op = USERCONTROL_CONNOP_ADD; // The new user is about to connect. It must be used in OnServerMessage of CServer.

Op-> userid = userid;

Conndata-> pThread = this;

Memset (& sockAddr, 0, sizeof (sockAddr ));

NSockAddrLen = sizeof (sockAddr );

BResult = socket-> GetPeerName (SOCKADDR *) & sockAddr, & nSockAddrLen );

If (bResult)

{

Conndata-> port = ntohs (sockAddr. sin_port );

# Ifdef _ UNICODE

_ Tcscpy (conndata-> ip, ConvFromLocal (inet_ntoa (sockAddr. sin_addr); // copy the string

# Else

_ Tcscpy (conndata-> ip, inet_ntoa (sockAddr. sin_addr ));

# Endif

}

// Send a message to the global hMainWnd,

// The wParam type of the message is FSM_CONNECTIONDATA, indicating that the message is a connection-related message. The parameter is t_connop.

// These are used to process the message in WindowProc of the CServer. After the message is processed, it will be displayed below the admin window.

// Information similar to 000001 (not logged in) 127.0.0.1

SendNotification (FSM_CONNECTIONDATA, (LPARAM) op );

If (ssl) // SSL-related, you can skip this step first.

If (! Socket-> InitImplicitSsl ())

Return;

Socket-> AsyncSelect (FD_READ | FD_WRITE | FD_CLOSE); // establishes a listener relationship for these events on the socket

// SendStatus still calls the SendNotification method, but the sent parameter is FSM_STATUSMESSAGE,

// Therefore, the processing in CServer is not the same

Socket-> SendStatus (_ T ("Connected, sending welcome message..."), 0 );

// In this case, the lower part of the admin window displays a message similar to (000003) 3:26:47-(not logged in) (127.0.0.1)> Connected, sending welcome message...

// Format the welcome information below

CStdString msg = m_pOptions-> GetOption (OPTION_WELCOMEMESSAGE );

If (m_RawWelcomeMessage! = Msg)

{

M_RawWelcomeMessage = msg;

M_ParsedWelcomeMessage.clear ();

Msg. Replace (_ T ("%"), _ T ("\ 001 "));

Msg. Replace (_ T ("% v"), GetVersionString ());

Msg. Replace (_ T ("\ 001"), _ T ("% "));

ASSERT (msg! = _ T (""));

Int oldpos = 0;

Msg. Replace (_ T ("\ r \ n"), _ T ("\ n "));

Int pos = msg. Find (_ T ("\ n "));

CStdString line;

While (pos! =-1)

{

ASSERT (pos );

M_ParsedWelcomeMessage.push_back (_ T ("220-") + msg. Mid (oldpos, pos-oldpos ));

Oldpos = pos + 1;

Pos = msg. Find (_ T ("\ n"), oldpos );

}

Line = msg. Mid (oldpos );

If (line! = _ T (""))

M_ParsedWelcomeMessage.push_back (_ T ("220") + line );

Else

{

M_ParsedWelcomeMessage.back () [3] = 0;

}

}

// HideStatus indicates whether to send this welcome message to admin port

Bool hideStatus = m_pOptions-> GetOptionVal (OPTION_WELCOMEMESSAGE_HIDE )! = 0;

ASSERT (! M_ParsedWelcomeMessage.empty ());

For (std: list : Iterator iter = m_ParsedWelcomeMessage.begin (); iter! = M_ParsedWelcomeMessage.end (); iter ++)

// Send the message to the socket Client and send the message to the admin port. The parameter sent is FSM_STATUSMESSAGE.

If (! Socket-> Send (* iter ,! HideStatus ))

Break;

// Run here. The welcome information appears on the client logon interface and in the admin window, similar:

// (000003) 3:27:19-(not logged in) (127.0.0.1)> 220-FileZilla Server version 0.9.18 beta

// (000003) 3:27:22-(not logged in) (127.0.0.1)> 220-written by Tim Kosse (Tim.Kosse@gmx.de)

// (000003) 3:27:29-(not logged in) (127.0.0.1)> 220 Please visit http://sourceforge.net/projects/filezilla/

Through the complete description in this article, you should know the source code of FileZilla and hope to help you!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.