青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大漠落日

while(!dead) study++;
posts - 46, comments - 126, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

FileZilla Server源碼分析(4)

Posted on 2010-06-25 11:11 亂78糟 閱讀(1237) 評論(0)  編輯 收藏 引用 所屬分類: 開源

    本節的分析是基于本系列第二篇FileZilla Server源碼分析(2之上,嚴格意義上來說是更為詳細的分析,深入了解CAsyncSocketEx的實現,我將挑出重要的函數一一分析。

    函數名都為紅色粗體,并且帶一對小括號,如果括號不含有字符“...”表示該函數無參數,否則有參數,具體什么參數不具體指明。變量均為黑色粗體。  


    首先來看一下該類的構造函數CAsyncSocketEx(),構造函數完成的是部分成員變量的初始化工作,其中最重要的是一個結構體變量m_SocketData,它的原型為:
   
    //Strucure to hold the socket data
    struct t_AsyncSocketExData
    {
        SOCKET hSocket; 
//Socket handle
        int nSocketIndex; //Index of socket, required by CAsyncSocketExHelperWindow
        int nFamily;
        addrinfo 
*addrInfo, *nextAddr; // Iterate through protocols on connect failure
        bool onCloseCalled; // Set to true on first received OnClose event
    } m_SocketData;

    還有m_pLocalAsyncSocketExThreadData的原型為:
//Pointer to the data of the local thread
    struct t_AsyncSocketExThreadData
    {
        CAsyncSocketExHelperWindow 
*m_pHelperWindow;
        
int nInstanceCount;
        DWORD nThreadId;
        std::list
<CAsyncSocketEx*> layerCloseNotify;
    } 
*m_pLocalAsyncSocketExThreadData;

    每個成員具體作用注釋已經比較清楚地說明了,后面用到的時候再指出。除了層NOLAYERS編譯(如果不明白,請看第二篇)此外還有一個宏條件編譯需要注意
#ifndef NOSOCKETSTATES
    m_nPendingEvents 
= 0//socket當前未決的網絡事件,例如FD_READ
    m_nState = notsock; //socket當前狀態
#endif //NOSOCKETSTATES

    析構函數~CAsyncSocketEx()調用函數Close()關閉socket,并調用FreeAsyncSocketExInstance()做清理工作。
    Close()函數中關閉層m_pFirstLayer->Close(),之后關閉成員變量m_SocketData.hSocket并且從輔助窗口m_pLocalAsyncSocketExThreadData->m_pHelperWindow記錄中移除掉這個socket,之后就是銷毀各種資源如地址、代理層等,有一個細節,不明白的可以MSDN,不細說了。
   if (m_hAsyncGetHostByNameHandle)
        WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
    m_hAsyncGetHostByNameHandle 
= NULL;

    再說FreeAsyncSocketExInstance()之前先說對應的函數InitAsyncSocketExInstance(),這兩個函數干的活都和一個static變量m_spAsyncSocketExThreadDataList有關,一個初始化,一個銷毀m_pLocalAsyncSocketExThreadData保存了當前線程的id和輔助窗口的指針。

    Create(...)函數創建代理層或者自身的socket以及做綁定到輔助窗口等操作。如果定義了使用代理層,那么所有關于socket的操作都會被代理層攔截,如create,listen,connect,accpet,recv,send,但是不包括bind,因為代理層create的時候已經提前綁定過了。
    TriggerEvent(...)這個函數用來觸發程序員指定的網絡事件,例如CControlSocket類中的Send(...)函數就調用了TriggerEvent(FD_WRITE)來觸發寫操作。它通過PosetMessage給輔助窗口,然后窗口通過消息處理函數WindowProc(...)處理這種種消息(詳細請參考第二節)。
   
    與代理層相關的函數,如AddLayer(...)RemoveAllLayers()等,還有設置獲取各種信息的函數如GetSockOpt()就不在詳述了。

    下面再補充之前函數WindowProc(...)關于網絡事件的詳細處理,僅僅針對非代理層的處理:
//if (!pSocket->m_pFirstLayer)
//{
   switch (nEvent)
   {
    
case FD_READ:
       
if (pSocket->GetState() == connecting && !nErrorCode)
        {
            pSocket
->m_nPendingEvents |= FD_READ; //如果正在連接,那么將讀事件加入未決事件變量里
            break;
        }
        
else if (pSocket->GetState() == attached)//已綁定成功的設置為連接成功
             pSocket->SetState(connected);
        
if (pSocket->GetState() != connected)    //如果還沒有連接成功,跳出
             break;

        
// Ignore further FD_READ events after FD_CLOSE has been received
        if (pSocket->m_SocketData.onCloseCalled)
            
break;
        
if (pSocket->m_lEvent & FD_READ)
        {
             DWORD nBytes 
= 0;
             
if (!nErrorCode)
             
if (!pSocket->IOCtl(FIONREAD, &nBytes)) //獲取要可讀的字節數
                  nErrorCode = WSAGetLastError();
             
if (nErrorCode)
                  pSocket
->SetState(aborted);    //出錯
             if (nBytes != 0 || nErrorCode != 0//通知socket已經有數據可以讀了
                  pSocket->OnReceive(nErrorCode);
         }
         
break;
   
case FD_FORCEREAD:
       
//除了不用獲取去可讀的字節數之外,完全可FD_READ一樣,這是作者自定義的類型
         break;
   
case FD_WRITE:
       
//前面的狀態判斷和FD_READ類似,不再詳述
       if (pSocket->m_lEvent & FD_WRITE)
       {
            
if (nErrorCode)
                pSocket
->SetState(aborted);

            pSocket
->OnSend(nErrorCode);//通知socket已經有數據可以發送了
        }
        
break;
    
case FD_CONNECT:
        
if (pSocket->GetState() == connecting)
        {
            
if (nErrorCode && pSocket->m_SocketData.nextAddr)  //有多個地址?
            {
                 
if (pSocket->TryNextProtocol())  //嘗試下一個協議地址
                      break;
             }
                 pSocket
->SetState(connected);
        }
        
else if (pSocket->GetState() == attached && !nErrorCode)
             pSocket
->SetState(connected);
        
if (pSocket->m_lEvent & FD_CONNECT)
             pSocket
->OnConnect(nErrorCode);
        
if (!nErrorCode)
        {
             
//判斷未決事件中是否期望的讀寫事件,如果有,通知socket
             if ((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected)
                 pSocket
->OnReceive(0);
             
if ((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected)
                 pSocket
->OnReceive(0);
             
if ((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected)
                  pSocket
->OnSend(0);
         }
         pSocket
->m_nPendingEvents = 0;
         
break;
    
case FD_ACCPET:
         
//如果不是監聽或已經綁定狀態,跳出
         if (pSocket->GetState() != listening && pSocket->GetState() != attached)
              
break;
         
if (pSocket->m_lEvent & FD_ACCEPT)
              pSocket
->OnAccept(nErrorCode);//通知
         break;
    
case FD_CLOSE:
         
//沒有連接或綁定,跳出
         if (pSocket->GetState() != connected && pSocket->GetState() != attached)
              
break;

         
// If there are still bytes left to read, call OnReceive instead of
         
// OnClose and trigger a new OnClose
         DWORD nBytes = 0;
         
if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
         {
              
//作者的注釋很清楚,如果關閉的時候還有數據可讀,將當前pSocket->m_SocketData.onCloseCalled 設置為TRUE
              
//以表示需要再一次調用關閉函數OnClose
              if (nBytes > 0)
              {
                   
// Just repeat message.
                   PostMessage(hWnd, message, wParam, lParam);
                   pSocket
->m_SocketData.onCloseCalled = true;                               
                   pSocket
->OnReceive(WSAESHUTDOWN);
                   
break;
               }
          }

          pSocket
->SetState(nErrorCode?aborted:closed);
          pSocket
->OnClose(nErrorCode);
          
break;
   }
//}

   本節是對第二節的一個小補充,也算是對MS的CAsyncSocket類的一個另類剖析吧。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美大片第1页| 狠狠色丁香婷婷综合| 99精品视频免费观看视频| 久久久久久久高潮| 亚洲欧美国产制服动漫| 亚洲乱码精品一二三四区日韩在线 | 99热免费精品在线观看| 蜜臀91精品一区二区三区| 久久在精品线影院精品国产| 另类尿喷潮videofree| 欧美电影免费观看高清| 欧美高清在线一区二区| 亚洲国产毛片完整版| 亚洲国产精品视频一区| 亚洲欧洲精品一区二区三区不卡| 亚洲高清中文字幕| 亚洲精品少妇| 亚洲一卡二卡三卡四卡五卡| 亚洲欧美日韩另类| 欧美在线观看你懂的| 美女黄色成人网| 欧美日韩一区二区精品| 国产欧美日韩亚洲| 亚洲国产日日夜夜| 亚洲一区一卡| 久久综合久色欧美综合狠狠| 欧美黄色aaaa| 宅男精品视频| 久久精品日产第一区二区| 欧美高清在线视频| 欧美视频不卡| 一区二区三区我不卡| 99热免费精品在线观看| 午夜影院日韩| 亚洲高清二区| 亚洲一区二区三区色| 蜜桃久久av一区| 国产精品视频yy9099| 在线看日韩欧美| 美女爽到呻吟久久久久| 亚洲无限av看| 99re亚洲国产精品| 亚洲四色影视在线观看| 亚洲午夜激情| 久久久夜精品| 久久日韩精品| 欧美性猛交99久久久久99按摩| 欧美劲爆第一页| 欧美午夜剧场| 亚洲电影免费观看高清完整版在线观看 | 久久综合色播五月| 欧美午夜激情在线| 亚洲国产欧美一区二区三区同亚洲| 亚洲香蕉网站| 亚洲国产第一页| 亚洲综合色噜噜狠狠| 欧美国产一区在线| 一区二区三区在线视频观看| 性欧美videos另类喷潮| 亚洲靠逼com| 蜜桃av久久久亚洲精品| 国产一区二区三区免费在线观看 | 美女黄毛**国产精品啪啪| 亚洲天堂av电影| 欧美日韩国产免费| 亚洲裸体俱乐部裸体舞表演av| 久久精品五月婷婷| 欧美亚洲一区三区| 国产一区二区三区精品欧美日韩一区二区三区 | 亚洲精品国产精品国自产观看浪潮| 久久九九热免费视频| 国产麻豆日韩| 亚洲欧美日韩精品久久亚洲区| 久久免费视频一区| 亚洲视频综合在线| 亚洲电影观看| 欧美成人综合一区| 亚洲人成免费| 欧美性久久久| 亚洲综合欧美| 亚洲一区二区精品视频| 欧美日韩成人在线| 亚洲国产精品999| 久久本道综合色狠狠五月| 99精品国产在热久久| 欧美日韩免费在线| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲另类自拍| 国产精品久久久一区二区| 亚洲一区二区三区欧美 | 亚洲精品在线观看免费| 欧美精品色一区二区三区| 最近中文字幕日韩精品| 亚洲精品一区二区三区av| 欧美日韩免费高清| 性欧美18~19sex高清播放| 久久精品三级| 亚洲精品国产精品国产自| 亚洲精品久久在线| 国产精品亚洲精品| 久久一区二区三区四区| 欧美成人精品一区二区| 亚洲永久免费视频| 久久电影一区| 亚洲开发第一视频在线播放| 一区二区三区四区国产精品| 国产自产在线视频一区| 亚洲国产精品一区| 国产精品网站在线| 欧美mv日韩mv国产网站| 欧美午夜美女看片| 久久久久国产精品午夜一区| 欧美精品播放| 午夜在线视频观看日韩17c| 久久人人爽国产| 国产精品99久久久久久宅男| 久久久99精品免费观看不卡| 一本色道久久综合亚洲精品高清 | 亚洲图片在区色| 欧美性猛片xxxx免费看久爱| 久久欧美肥婆一二区| 国产精品一区二区久久国产| 日韩午夜三级在线| 美日韩精品免费观看视频| 亚洲青色在线| 亚洲人成在线观看一区二区| 国产精品色一区二区三区| 欧美成人精品在线| 国产精品美腿一区在线看 | 欧美一区二区在线视频| 农村妇女精品| 久久久www成人免费毛片麻豆| 欧美成人午夜| 久久影院午夜片一区| 国产美女精品免费电影| 亚洲国产精品久久久久婷婷884 | 欧美日韩第一区| 免费看亚洲片| 国产视频在线观看一区| 亚洲精品在线观看视频| 亚洲日本电影| 欧美一区日本一区韩国一区| 一区二区三区.www| 免费中文日韩| 免费毛片一区二区三区久久久| 国产精品日日做人人爱| 日韩视频精品在线| 亚洲最新视频在线| 美女黄网久久| 欧美国产亚洲另类动漫| 精品成人一区二区| 午夜精品久久久久久久99水蜜桃 | 久久女同互慰一区二区三区| 小嫩嫩精品导航| 91久久久久| 久久精品国产精品| 欧美激情四色| 欧美国产一区二区在线观看 | 模特精品裸拍一区| 一区二区三区高清视频在线观看| 欧美黄色aa电影| 久久精品成人一区二区三区蜜臀| 欧美亚洲视频在线观看| 午夜欧美不卡精品aaaaa| 国产精品嫩草99a| 日韩午夜免费| 久久午夜视频| 亚洲第一综合天堂另类专| 欧美一区二区三区电影在线观看| 欧美一级欧美一级在线播放| 国产精品久久久久久福利一牛影视 | 亚洲精品网站在线播放gif| 久久久国产一区二区三区| 亚洲一区二区三区成人在线视频精品 | 久久伊伊香蕉| 影音先锋中文字幕一区| 免费观看欧美在线视频的网站| 欧美福利在线观看| 一本一本久久a久久精品综合妖精| 欧美日韩精品一区二区在线播放| 亚洲视频久久| 久久全球大尺度高清视频| 在线免费观看日韩欧美| 母乳一区在线观看| 亚洲精品一品区二品区三品区| 宅男在线国产精品| 国产午夜一区二区三区| 蜜桃av噜噜一区二区三区| 日韩视频免费看| 欧美一级免费视频| 在线观看视频一区二区欧美日韩| 欧美成人亚洲| 亚洲午夜电影网| 久久综合给合| 亚洲视频日本| 亚洲福利视频三区| 欧美性猛交xxxx免费看久久久| 欧美一区二视频| 亚洲精选视频在线| 久久久蜜桃一区二区人|