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

大漠落日

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

FileZilla Server源碼分析(4)

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

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

    函數(shù)名都為紅色粗體,并且?guī)б粚π±ㄌ枺绻ㄌ柌缓凶址?#8220;...”表示該函數(shù)無參數(shù),否則有參數(shù),具體什么參數(shù)不具體指明。變量均為黑色粗體。  


    首先來看一下該類的構造函數(shù)CAsyncSocketEx(),構造函數(shù)完成的是部分成員變量的初始化工作,其中最重要的是一個結構體變量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當前狀態(tài)
#endif //NOSOCKETSTATES

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

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

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

    下面再補充之前函數(shù)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)) //獲取要可讀的字節(jié)數(shù)
                  nErrorCode = WSAGetLastError();
             
if (nErrorCode)
                  pSocket
->SetState(aborted);    //出錯
             if (nBytes != 0 || nErrorCode != 0//通知socket已經有數(shù)據(jù)可以讀了
                  pSocket->OnReceive(nErrorCode);
         }
         
break;
   
case FD_FORCEREAD:
       
//除了不用獲取去可讀的字節(jié)數(shù)之外,完全可FD_READ一樣,這是作者自定義的類型
         break;
   
case FD_WRITE:
       
//前面的狀態(tài)判斷和FD_READ類似,不再詳述
       if (pSocket->m_lEvent & FD_WRITE)
       {
            
if (nErrorCode)
                pSocket
->SetState(aborted);

            pSocket
->OnSend(nErrorCode);//通知socket已經有數(shù)據(jù)可以發(fā)送了
        }
        
break;
    
case FD_CONNECT:
        
if (pSocket->GetState() == connecting)
        {
            
if (nErrorCode && pSocket->m_SocketData.nextAddr)  //有多個地址?
            {
                 
if (pSocket->TryNextProtocol())  //嘗試下一個協(xié)議地址
                      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:
         
//如果不是監(jiān)聽或已經綁定狀態(tài),跳出
         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))
         {
              
//作者的注釋很清楚,如果關閉的時候還有數(shù)據(jù)可讀,將當前pSocket->m_SocketData.onCloseCalled 設置為TRUE
              
//以表示需要再一次調用關閉函數(shù)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;
   }
//}

   本節(jié)是對第二節(jié)的一個小補充,也算是對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>
            欧美成人伊人久久综合网| 午夜综合激情| 免费视频一区| 久久精品99国产精品日本| 国产日韩精品一区二区浪潮av| 亚洲一区二区三区影院| 在线亚洲欧美视频| 国产美女精品视频| 久久夜色精品一区| 免费视频一区| 一区二区国产精品| 亚洲一区二区在线| 极品少妇一区二区三区精品视频 | 欧美激情第五页| 99国产精品久久久| 亚洲女人天堂成人av在线| 国产亚洲一级高清| 亚洲国产日韩欧美一区二区三区| 另类酷文…触手系列精品集v1小说| 亚洲激情综合| 在线视频亚洲| 在线国产日韩| 一区二区三区久久久| 国产亚洲精品久| 亚洲激情成人网| 国产欧美日韩另类视频免费观看| 老妇喷水一区二区三区| 欧美日韩国产123| 久久久久久久久久久一区 | 久久精品91久久香蕉加勒比| 亚洲欧洲精品一区二区三区不卡| 一区二区高清在线| 激情婷婷久久| 亚洲午夜羞羞片| 亚洲黄色av| 亚洲欧美制服另类日韩| 亚洲欧洲精品一区二区三区| 午夜精品久久久久久久99水蜜桃| 亚洲欧洲日本mm| 欧美在线啊v| 欧美jizzhd精品欧美巨大免费| 榴莲视频成人在线观看| 欧美一区二区三区日韩视频| 欧美/亚洲一区| 久久精品国产免费| 欧美日韩国产区| 欧美顶级艳妇交换群宴| 国产三级精品三级| 亚洲图片欧洲图片日韩av| 亚洲麻豆av| 久久婷婷亚洲| 久久麻豆一区二区| 国产精品美女久久久久av超清 | 亚洲一区二区三区色| 欧美成人r级一区二区三区| 久久久九九九九| 国产精品综合色区在线观看| 亚洲另类视频| 一区二区三区精品视频在线观看| 久久久国产精品一区| 久久se精品一区二区| 国产精品久久福利| 在线视频中文亚洲| 亚洲一区二区3| 欧美日韩一区二区国产| 亚洲美女中出| 亚洲综合国产激情另类一区| 欧美日韩成人在线视频| 亚洲精品久久嫩草网站秘色| 亚洲品质自拍| 欧美精品一区二区三区高清aⅴ| 模特精品在线| 亚洲国产精品视频| 欧美精品久久久久久久久久| 亚洲第一在线综合在线| 亚洲精品少妇| 欧美日韩亚洲一区在线观看| 日韩网站在线看片你懂的| 这里只有精品视频在线| 国产精品美腿一区在线看| 午夜国产精品视频| 久久久最新网址| 亚洲黄色在线观看| 欧美日韩视频第一区| 亚洲免费在线视频| 久久女同互慰一区二区三区| 在线成人激情| 欧美日本不卡| 亚洲欧美精品伊人久久| 久久影视三级福利片| 亚洲精品韩国| 国产精品久久午夜| 久久精品99| 99视频在线观看一区三区| 欧美一区二区视频在线观看| 精品成人久久| 欧美日韩国产一区精品一区| 亚洲欧美文学| 亚洲国产成人精品久久| 亚洲欧美日韩另类| 伊人成年综合电影网| 欧美色网在线| 欧美伊人久久久久久午夜久久久久 | 欧美电影专区| 亚洲午夜在线视频| 欧美成人综合一区| 亚洲一区亚洲| 久久色在线播放| 日韩一区二区电影网| 国产亚洲一区二区在线观看| 欧美大片一区二区三区| 亚洲主播在线观看| 亚洲娇小video精品| 久久精品国产第一区二区三区| 亚洲精品日本| 黄色av日韩| 国产伦精品一区二区三区高清| 嫩草影视亚洲| 欧美在线视频一区| 99国产精品国产精品毛片| 久久综合精品国产一区二区三区| 亚洲伊人网站| 亚洲精品国产精品国产自| 国产亚洲一区二区在线观看| 国产精品久久久久国产精品日日 | 久久本道综合色狠狠五月| 亚洲美女少妇无套啪啪呻吟| 欧美大片在线看| 久久久九九九九| 欧美在线观看视频在线| 一区二区三区高清不卡| 亚洲精品国产精品国自产观看| 精品999久久久| 国产综合婷婷| 国产手机视频精品| 国产免费观看久久黄| 国产精品狠色婷| 欧美日韩在线精品| 欧美日韩在线高清| 欧美日韩综合一区| 欧美日韩一区三区| 欧美色中文字幕| 国产精品成人一区二区三区夜夜夜| 欧美电影免费观看高清| 免费看成人av| 欧美激情乱人伦| 欧美激情自拍| 欧美理论电影网| 欧美日韩一二三四五区| 欧美日韩一区二区国产| 国产精品成人av性教育| 国产精品va在线| 国产精品视频一区二区三区| 国产精品福利久久久| 欧美午夜欧美| 国产欧美日韩免费看aⅴ视频| 国产精品成人免费| 国产欧美精品国产国产专区| 国产伦理一区| 国色天香一区二区| 亚洲黄色影片| 亚洲午夜精品久久| 欧美专区第一页| 美女黄网久久| 亚洲欧洲一区二区天堂久久| 日韩午夜剧场| 亚洲免费在线视频| 久久精品亚洲一区二区| 免费观看久久久4p| 欧美三区视频| 国产婷婷成人久久av免费高清 | 欧美成人综合| 国产精品国产a| 黄色av一区| 夜夜夜久久久| 久久精品99久久香蕉国产色戒| 免费成人黄色片| 99国产欧美久久久精品| 欧美一区二区视频在线观看| 美乳少妇欧美精品| 国产精品国产馆在线真实露脸| 国内精品伊人久久久久av一坑| 亚洲欧洲日本在线| 欧美在线观看一区| 欧美日韩精品福利| 国产精自产拍久久久久久蜜| 亚洲第一精品久久忘忧草社区| 一本色道久久综合狠狠躁篇怎么玩| 亚洲欧美日韩国产中文| 久久亚洲私人国产精品va| 亚洲第一区在线观看| 亚洲综合精品四区| 欧美寡妇偷汉性猛交| 国产视频一区在线观看| 亚洲视频中文| 欧美成人小视频| 欧美一区免费视频| 欧美三级第一页| 亚洲人久久久| 美女视频黄 久久|