UC故事2011/11/27 - 1


1. 关于connection的定时器

#define TIME_CONF_CONNECT_TIME                (1000 * 30)

改成

#define TIME_CONF_CONNECT_TIME                (1000 * 5)

试试效果,看5秒的效果是什么。

注:结果没有什么感觉,恢复原值。


2. CRtReactorBase::ProcessHandleEvent(...)

RtResult CRtReactorBase::
ProcessHandleEvent(RT_HANDLE aFd, IRtEventHandler::MASK aMask,
                   RtResult aReason, BOOL aIsNotify, BOOL aDropConnect)
{

...

        else {
            if (maskActual & IRtEventHandler::ACCEPT_MASK
                || maskActual & IRtEventHandler::READ_MASK)
            {
                nOnCall = eleFind.m_pEh->OnInput(aFd);
            }
            if ((nOnCall == 0 || nOnCall == -2) &&
                (maskActual & IRtEventHandler::CONNECT_MASK
                || maskActual & IRtEventHandler::WRITE_MASK))
            {
                nOnCall = eleFind.m_pEh->OnOutput(aFd);
            }
        }

...

}

注:此函数的基本功能就是根据event的类型,调用event handler的OnInput或OnOutput函数,以进行输入或输出操作。


3. Client启动后的thread 总结

启动后主要有几个线程:

* 用户UI线程(主线程)

ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::WindowProc(HWND__ * 0x020a89b8, unsigned int 1, unsigned int 0, long 1269856) line 2110 + 37 bytes
USER32! 77d18734()
USER32! 77d2bdf1()
USER32! 77d28ea0()
USER32! 77d2ce7c()
NTDLL! 7c92e473()
USER32! 77d2e442()
USER32! 77d2e4dc()
WTL::CFrameWindowImplBase<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::Create(HWND__ * 0x00000000, ATL::_U_RECT {...}, const char * 0x001366e0, unsigned long 114229248, unsigned long 262400, ATL::_U_MENUorID {...}, unsigned short 49962, void * 0x00000000) line 456 + 91 bytes
WTL::CFrameWindowImpl<CMainFrame,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::Create(HWND__ * 0x00000000, ATL::_U_RECT {...}, const char * 0x001366e0, unsigned long 114229248, unsigned long 262400, HMENU__ * 0x457a0871, void * 0x00000000) line 1196
WTL::CFrameWindowImpl<CMainFrame,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::CreateEx(HWND__ * 0x00000000, ATL::_U_RECT {...}, unsigned long 0, unsigned long 0, void * 0x00000000) line 1221 + 42 bytes
Run(char * 0x00151f28, int 1) line 195 + 35 bytes
LaunchConf(HINSTANCE__ * 0x00400000, char * 0x00151f28, int 1) line 318 + 13 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f28, int 1) line 85 + 20 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()

* 网络线程


CRtReactorBase::ProcessHandleEvent(void * 0xffffffff, long 256, int 0, int 1, int 0) line 324 + 18 bytes
CRtReactorWin32Message::Win32SocketWndProc(HWND__ * 0x00130aa2, unsigned int 1058, unsigned int 4294967295, long 256) line 115
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d196c7()
CRtReactorWin32Message::RunEventLoop() line 262 + 15 bytes
CRtThreadReactor::OnThreadRun() line 67 + 19 bytes
CRtThread::ThreadProc(void * 0x020a7ef0) line 151 + 13 bytes
_threadstartex(void * 0x020a7fa0) line 227 + 13 bytes
KERNEL32! 7c80b729()

* 一个同步用的线程(Q:具体功能是什么啊

NTDLL! 7c92e514()
KERNEL32! 7c802542()
CRtConditionVariableThread::Wait(CRtTimeValue * 0x00000000) line 190 + 26 bytes
CRtEventQueueUsingConditionVariable::PopOrWaitPendingEvents(std::list<IRtEvent *,std::allocator<IRtEvent *> > & {...}, CRtTimeValue * 0x00000000, unsigned long 4294967295) line 159 + 15 bytes
CRtThreadTaskWithEventQueueOnly::OnThreadRun() line 32 + 22 bytes
CRtThread::ThreadProc(void * 0x020ac8b8) line 151 + 13 bytes
_threadstartex(void * 0x020ac9d8) line 227 + 13 bytes
KERNEL32! 7c80b729()



4. 关于WSAsyncSelect()的总结

* STACK TRACE

CRtReactorWin32AsyncSelect::DoAsyncSelect_i(void * 0x00000664, long 63) line 366
CRtReactorWin32AsyncSelect::OnHandleRegister(void * 0x00000664, long 2, IRtEventHandler * 0x020ab300) line 344
CRtReactorBase::RegisterHandler(IRtEventHandler * 0x020ab300, long 2) line 219 + 31 bytes
CRtConnectorTcpT<CRtConnectorWrapper,CRtTransportTcp,CRtSocketStream>::Connect_i(CRtTransportTcp * 0x020ab568, const CRtInetAddr & {...}) line 202 + 25 bytes
CRtConnectorTcpT<CRtConnectorWrapper,CRtTransportTcp,CRtSocketStream>::Connect(const CRtInetAddr & {...}, CRtInetAddr * 0x00000000) line 82 + 22 bytes
CRtConnectorWrapper::AsycConnect(IRtAcceptorConnectorSink * 0x020ab428, const CRtInetAddr & {...}, CRtTimeValue * 0x020ad41c, CRtInetAddr * 0x00000000) line 109 + 26 bytes
CConnConnectorT<CRtConnRlbTcpClient>::AsycConnect(IRtAcceptorConnectorSink * 0x020ad074, const CRtInetAddr & {...}, CRtTimeValue * 0x020ad41c, CRtInetAddr * 0x00000000) line 357 + 84 bytes
CEventAsycConnect::OnEventFire() line 187 + 74 bytes
CRtEventQueueBase::ProcessOneEvent(IRtEvent * 0x020ad3f0) line 229 + 12 bytes
CRtEventQueueBase::ProcessEvents(const std::list<IRtEvent *,std::allocator<IRtEvent *> > & {...}) line 217
CRtReactorBase::ProcessHandleEvent(void * 0xffffffff, long 256, int 0, int 1, int 0) line 324 + 18 bytes
CRtReactorWin32Message::Win32SocketWndProc(HWND__ * 0x000a09a8, unsigned int 1058, unsigned int 4294967295, long 256) line 115
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d196c7()
CRtReactorWin32Message::RunEventLoop() line 262 + 15 bytes
CRtThreadReactor::OnThreadRun() line 67 + 19 bytes
CRtThread::ThreadProc(void * 0x020a7ef0) line 151 + 13 bytes
_threadstartex(void * 0x020a7fa0) line 227 + 13 bytes
KERNEL32! 7c80b

* CODE

RtResult CRtReactorWin32AsyncSelect::
DoAsyncSelect_i(RT_HANDLE aFd, IRtEventHandler::MASK aMask)
{
    long lEvent = 0;
    if (aMask & IRtEventHandler::CONNECT_MASK)
        lEvent |= FD_CONNECT;
    if (aMask & IRtEventHandler::ACCEPT_MASK)
        lEvent |= FD_ACCEPT;
    if (aMask & IRtEventHandler::READ_MASK)
        lEvent |= FD_READ;
    if (aMask & IRtEventHandler::WRITE_MASK)
        lEvent |= FD_WRITE;

    if (lEvent != 0)
        lEvent |= FD_CLOSE;

    else
        return RT_OK;
}

注:在网络线程里完成了对WSAAsyncSelect的设置,从而当网络线程中发生相应的网络事件(WM_WIN32_SOCKET_SELECT自定义)的时候,消息处理函数CRtReactorWin32Message::Win32SocketWndProc对其进行相应处理。

static LRESULT CALLBACK Win32SocketWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);


5. socket的实例化及WSAAsyncSelect

* STACK TRACE:

CRtReactorWin32AsyncSelect::DoAsyncSelect_i(void * 0x00000664, long 63) line 366
CRtReactorWin32AsyncSelect::OnHandleRegister(void * 0x00000664, long 2, IRtEventHandler * 0x020ab300) line 344
CRtReactorBase::RegisterHandler(IRtEventHandler * 0x020ab300, long 2) line 219 + 31 bytes
CRtConnectorTcpT<CRtConnectorWrapper,CRtTransportTcp,CRtSocketStream>::Connect_i(CRtTransportTcp * 0x020ab568, const CRtInetAddr & {...}) line 202 + 25 bytes
CRtConnectorTcpT<CRtConnectorWrapper,CRtTransportTcp,CRtSocketStream>::Connect(const CRtInetAddr & {...}, CRtInetAddr * 0x00000000) line 82 + 22 bytes
CRtConnectorWrapper::AsycConnect(IRtAcceptorConnectorSink * 0x020ab428, const CRtInetAddr & {...}, CRtTimeValue * 0x020ad41c, CRtInetAddr * 0x00000000) line 109 + 26 bytes

* CODE: CRtConnectorTcpT::Connect()

    // interface IRtConnectorInternal
    virtual int Connect(const CRtInetAddr &aAddr, CRtInetAddr *aAddrLocal = NULL)
    {
        int nRet = 0;
        const CRtInetAddr *pAddrConnect = &aAddr;
        if (aAddrLocal)
            m_addrLocal = *aAddrLocal;

         ......
        
        RT_ASSERTE_RETURN(!m_pTransport, -1);
        m_pTransport = new UpTrptType(m_pReactor);                   // 此处生成了UpTrptType的实例,其实是CRtTransportTcp的实例。
        if (!m_pTransport)
            return -1;

        nRet = Connect_i(m_pTransport, *pAddrConnect);
        if (nRet == 0) {
            // it rarely happens. we have to OnConnectIndication(RT_OK) to upper layer.
            RT_WARNING_TRACE_THIS("CRtConnectorTcpT::Connect, connect return 0.");
            nRet = m_pReactor->NotifyHandler(this, IRtEventHandler::WRITE_MASK);
        }
        else if (nRet == 1)
            nRet = 0;
        return nRet;
    }


* CODE: CRtConnectorTcpT::Connect_I()

    int Connect_i(UpTrptType *aTrpt, const CRtInetAddr &aAddr)
    {
        int nRet;
        UpSockType &sockPeer = aTrpt->GetPeer();
        RT_ASSERTE(sockPeer.GetHandle() == RT_INVALID_HANDLE);
        
        if (m_addrLocal == CRtInetAddr::s_rtInetAddrNull)
            nRet = sockPeer.Open(FALSE);
        else
            nRet = sockPeer.Open(FALSE, m_addrLocal);
                ......

        if (sockPeer.Enable(RT_IPC_SAP::NON_BLOCK) == -1) {
            RT_ERROR_TRACE_THIS("CRtConnectorTcpT::Connect_i, Enable(NON_BLOCK) failed! err=" << RtGetSystemErrorInfo(errno));
            return -1;
        }

                ......

        /// we regiester CONNECT_MASK prior to connect() to avoid lossing OnConnect()
        RtResult rv = m_pReactor->RegisterHandler(this, IRtEventHandler::CONNECT_MASK);
        if (RT_FAILED(rv))
            return -1;

        nRet = ::connect((RT_SOCKET)sockPeer.GetHandle(),
                          reinterpret_cast<const struct sockaddr *>(aAddr.GetPtr()),
                          aAddr.GetSize());                               // 此处,终于修成成果,连接建立,tcpview.exe能看到了。
                ......

    }


总结一下:

# 网络线程启动

# 创建到远端(server)的连接Socket

# WSAAsyncSelect绑定到CRtReactorWin32Message::Win32SocketWndProc

# 连接server(::Connect())


5. Client启动过程总结,关注以下几点:

* 线程

* 网络端口

* 与服务器端的各种交互

* 网络线程与主线程之间的交互方式






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值