成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

FileZilla 源代碼分析6

系統(tǒng) Linux
FileZilla是一個免費開源的FTP客戶端軟件,分為客戶端版本和服務(wù)器版本,具備所有的FTP軟件功能。可控性、有條理的界面和管理多站點的簡化方式使得Filezilla客戶端版成為一個方便高效的FTP客戶端工具,而FileZilla Server則是一個小巧并且可靠的支持FTP&SFTP的FTP服務(wù)器軟件。

FileZilla是一種快速、可信賴的FTP客戶端以及服務(wù)器端開放源代碼程式,具有多種特色、直覺的接口。本文就給大家分析下FileZilla的源代碼。

  CListenSocket是CAsyncSocketEx類的子類,在啟動的時候用來監(jiān)聽21端口。

  pListenSocket->Create(nPort, SOCK_STREAM, FD_ACCEPT, NULL)

  可見,CListenSocket只處理FD_ACCEPT消息。

  看一下:

  void CListenSocket::OnAccept(int nErrorCode)

  {

  CAsyncSocketEx socket;

  if (!Accept(socket)) // 這里調(diào)用了win API: accept方法,建立了一個新連接,socket就這個新連接的SOCKET

  {

  int nError = WSAGetLastError();

  CStdString str;

  str.Format(_T("Failure in CListenSocket::OnAccept(%d) - call to CAsyncSocketEx::Accept failed, errorcode

  %d"), nErrorCode, nError);

  SendStatus(str, 1);

  SendStatus(_T("If you use a firewall, please check your firewall configuration"), 1);

  return;

  }

  // 權(quán)限檢查,先不管

  if (!AccessAllowed(socket))

  {

  CStdStringA str = "550 No connections allowed from your IP\r\n";

  socket.Send(str, str.GetLength());

  return;

  }

  // 檢查FileZilla Server是否處于鎖定狀態(tài),即不允許建立新連接

  if (m_bLocked)

  {

  CStdStringA str = "421 Server is locked, please try again later.\r\n";

  socket.Send(str, str.GetLength());

  return;

  }

  // 下面從可用的線程中,找出目前負(fù)荷最小的線程,即線程中負(fù)責(zé)的connection最少的線程

  int minnum = 255*255*255;

  CServerThread *pBestThread=0;;

  for (std::list::iterator iter=m_pThreadList->begin(); iter!=m_pThreadList->end(); iter++)

  {

  int num=(*iter)->GetNumConnections();

  if (numIsReady()) // 找出connection最少的線程

  {

  minnum=num;

  pBestThread=*iter;

  if (!num)

  break;

  }

  }

  if (!pBestThread)

  {

  char str[] = "421 Server offline.";

  socket.Send(str, strlen(str)+1);

  socket.Close();

  return;

  }

  /* Disable Nagle algorithm. Most of the time single short strings get

  * transferred over the control connection. Waiting for additional data

  * where there will be most likely none affects performance.

  */

  BOOL value = TRUE;

  socket.SetSockOpt(TCP_NODELAY, &value, sizeof(value), IPPROTO_TCP); // 設(shè)置不使用Nagle算法,參見TCP協(xié)議Nagle算法部分

  SOCKET sockethandle = socket.Detach();

  pBestThread->AddSocket(sockethandle, m_ssl); // 轉(zhuǎn)交服務(wù)線程來處理

  CAsyncSocketEx::OnAccept(nErrorCode); // 父類的缺省處理為空

  }

  可見,CListenSocket::OnAccept主要工作是

  1、創(chuàng)建一個socket來接收新的客戶端連接

  2、進(jìn)行一些檢查設(shè)置,如權(quán)限檢查,Nagle算法設(shè)置等

  3、找到一個負(fù)荷最小的后臺服務(wù)線程,由交那個線程處理

  為了更清楚服務(wù)線程CServerThread的機制,先看回顧一下當(dāng)時這個服務(wù)線程是如何被創(chuàng)建的。

  CServer類的Create()片斷:

  for (int i = 0; i < num; i++) // 這里num是需要創(chuàng)建的服務(wù)線程的數(shù)量

  {

  int index = GetNextThreadNotificationID(); // 得到這個線程的一個標(biāo)識,即在線程數(shù)組std::vector

  m_ThreadNotificationIDs中的index

  CServerThread *pThread = new CServerThread(WM_FILEZILLA_SERVERMSG + index);

  m_ThreadNotificationIDs[index] = pThread;

  // If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state,

  // and will not run until the ResumeThread function is called.

  // If this value is zero, the thread runs immediately after creation.

  if (pThread->Create(THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED))

  {

  pThread->ResumeThread();

  m_ThreadArray.push_back(pThread);

  }

  }

  看一下pThread->Create(THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED),由于CServerThread繼承于CThread,因此調(diào)用了CThread的create:

  BOOL CThread::Create(int nPriority /*=THREAD_PRIORITY_NORMAL*/, DWORD dwCreateFlags /*=0*/)

  {

  m_hThread=CreateThread(0, 0, ThreadProc, this, dwCreateFlags, &m_dwThreadId); // 調(diào)用win api創(chuàng)建一個線程

  if (!m_hThread)

  {

  delete this;

  return FALSE;

  }

  ::SetThreadPriority(m_hThread, nPriority);

  return TRUE;

  }

  注意創(chuàng)建線程的時候,指定線程的初始狀態(tài)為CREATE_SUSPENDED。

  創(chuàng)建成功后,調(diào)用pThread->ResumeThread():

  DWORD CThread::ResumeThread()

  {

  // 下面使用win API:ResumeThread啟動這個線程,線程開動后, 會自動跑到ThreadProc函數(shù)(create時指定)

  DWORD res=::ResumeThread(m_hThread); // 這個函數(shù)過后,有兩個線程在跑,一個是剛才的主線程,一個是剛啟動的線程

  if (!m_started) // 主線程運行到這里,由于m_started還是0,所以通過下面的WaitForSingleObject,進(jìn)行了等待狀態(tài)

  {

  WaitForSingleObject(m_hEventStarted, INFINITE);

  }

  return res;

  }

  剛啟動的線程進(jìn)入了ThreadProc函數(shù):

  DWORD WINAPI CThread::ThreadProc(LPVOID lpParameter)

  {

  // 在CreateThread時指定的參數(shù)LPVOID lpParameter為this,即CThread

  return ((CThread *)lpParameter)->Run();

  }

  即運行Run方法:

  DWORD CThread::Run()

  {

  InitInstance(); // 這里CServerThread類重寫了這個方法,因此進(jìn)入CServerThread::InitInstance(),進(jìn)行了一些內(nèi)存變量的初始

  化

  // The SetEvent function sets the specified event object to the signaled state.

  SetEvent(m_hEventStarted); // 設(shè)置event為active,使得剛才在等待的主線程復(fù)活,繼續(xù)CServer的啟動工作

  m_started = true;

  MSG msg;

  while (GetMessage(&msg, 0, 0, 0)) // 進(jìn)入這個線程的消息循環(huán)

  {

  TranslateMessage(&msg);

  if (!msg.hwnd)

  OnThreadMessage(msg.message, msg.wParam, msg.lParam); // 調(diào)用OnThreadMessage處理消息

  DispatchMessage(&msg);

  }

  DWORD res=ExitInstance();

  delete this;

  return res;

  }

  可見,服務(wù)器啟動后,剛開始沒有消息時,CServerThread在GetMessage()時進(jìn)入了block狀態(tài),一旦有消息到來,這個服務(wù)線程就蘇醒,接著

  處理消息。

  下面回到最初的CListenSocket::OnAccept(),最后調(diào)用了pBestThread->AddSocket(sockethandle, m_ssl); // 轉(zhuǎn)交服務(wù)線程來處理

  仔細(xì)看一下后臺的服務(wù)線程是如何處理消息的。

  void CServerThread::AddSocket(SOCKET sockethandle, bool ssl)

  {

  // 調(diào)用了父類的方法

  PostThreadMessage(WM_FILEZILLA_THREADMSG, ssl ? FTM_NEWSOCKET_SSL : FTM_NEWSOCKET, (LPARAM)sockethandle);

  }

  接著:

  BOOL CThread::PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam)

  {

  // posts a message to the message queue of the specified thread.

  BOOL res=::PostThreadMessage(m_dwThreadId, message, wParam, lParam);;

  ASSERT(res);

  return res;

  }

  PostThreadMessage是windows API,作用是把消息message發(fā)送到線程m_dwThreadId,

  根據(jù)前面的代碼,在這里就是把消息WM_FILEZILLA_THREADMSG,以及參數(shù)FTM_NEWSOCKET, sockethandle發(fā)送到那個負(fù)荷最小的后臺服務(wù)線程,

  由于在啟動時,那個后臺線程處于GetMessage()的block中,因此收到這個消息到,那個后臺線程蘇醒,接著調(diào)用OnThreadMessage來處理這個WM_FILEZILLA_THREADMSG消息。

通過文章完整的描述,大家應(yīng)該知道了FileZilla 源代碼,希望對大家有幫助!

【編輯推薦】

  1. FileZilla簡單介紹
  2. FileZilla 源代碼分析1
  3. FileZilla 源代碼分析2
  4. FileZilla 源代碼分析3
  5. FileZilla 源代碼分析4
  6. FileZilla 源代碼分析5
  7. FileZilla:免費的服務(wù)器軟件
  8. FileZilla 3.3.1.0新版升級 修復(fù)bug
責(zé)任編輯:趙鵬 來源: 網(wǎng)絡(luò)轉(zhuǎn)載
相關(guān)推薦

2011-02-23 15:11:27

FileZilla

2011-02-23 15:33:42

FileZilla

2011-02-23 14:26:28

FileZilla

2011-02-23 15:21:06

FileZilla

2011-02-23 15:26:01

FileZilla

2011-02-23 13:47:33

FileZilla

2011-02-23 14:46:21

FileZilla

2011-02-23 14:16:43

FileZilla

2011-02-23 14:39:27

FileZilla

2011-03-01 16:25:37

FileZilla

2011-03-01 16:32:58

FileZilla

2011-03-01 16:19:27

FileZilla

2011-03-01 16:01:08

FileZilla

2022-09-20 11:23:51

黑客GTA 6游戲

2015-08-28 09:38:51

Linux源代碼分析工具

2018-05-25 14:16:55

NFS源代碼線程

2015-08-26 17:38:47

Linux源代碼

2009-07-02 13:59:35

JSP后臺

2011-08-24 15:42:38

LUA源代碼

2020-02-24 09:25:33

代碼開發(fā)工具
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 免费观看www | 青青草免费在线视频 | 久久精品国产一区二区电影 | 国产精品欧美一区二区三区 | 中文字幕日韩欧美 | 色婷婷综合在线观看 | 欧美精品一区久久 | 欧美一级做a爰片免费视频 国产美女特级嫩嫩嫩bbb片 | 国产乱码久久久久久 | 欧美国产日韩在线观看 | 亚洲精品美女视频 | 视频一区二区在线观看 | 91婷婷韩国欧美一区二区 | 日韩免费成人av | 国产视频一区二区 | 欧美视频成人 | 麻豆changesxxx国产| 欧美美女二区 | 日韩欧美三级电影 | 一区二区在线观看免费视频 | 精品国产乱码一区二区三区 | 亚洲高清在线 | 国产精品久久久久久婷婷天堂 | 国产蜜臀 | 91国在线 | 久久久久亚洲国产| 亚洲精品欧美一区二区三区 | 国产日产欧产精品精品推荐蛮挑 | 亚洲精品视频免费观看 | 99久久精品免费看国产高清 | 九九久久精品 | 久久久影院| 亚洲精品一区在线 | 国产精品欧美一区二区 | 做a的各种视频 | 国产探花在线精品一区二区 | 黄色成人在线观看 | 欧美日韩精品一区 | 欧美狠狠操 | 在线播放亚洲 | 国产九九精品 |