教程 | 服務端套接字類CxServerSocket


CxServerSocket的使用如下(以某個叫做CSomeClass的類的相關代碼為例):

一、聲明服務端套接字對象實例。

CxServerSocket m_ssLocalHost;

 二、設置服務端套接字事件通知方式。消息響應或回調函數,任選其一。服務端套接字事件有:接收到客戶端的連接請求。

void CSomeClass::PreSubclassWindow() 
{
    // TODO: Add your specialized code here and/or call the base class
    HWND hwnd = GetSafeHwnd();
    MSG msg = {hwnd, WM_SOCKET_EVENT};
    m_usRemoteHost.SetWindowMessage(&msg);
    m_csRemoteHost.SetWindowMessage(&msg);
    m_ssLocalHost.SetWindowMessage(&msg);

    if (m_btCSMode == CSM_SERVER)
        ListenRemoteHost();

    CStatic::PreSubclassWindow();
}

 三、偵聽客戶端連接請求

BOOL CSomeClass::ListenRemoteHost()
{
    char szIPAddr[MAX_IPV6];
    if (CxSocket::GetLocalHost(szIPAddr))
        return m_ssLocalHost.Listen(szIPAddr, NETPORT_NETWORK_COMM);
    else
        return FALSE;
}

  NETPORT_NETWORK_COMM是一個自定義的TCP端口值,只要不與公用端口沖突就行。

 四、處理消息響應或函數回調。
1.消息響應

BEGIN_MESSAGE_MAP(CSomeClass, CStatic)
    //{{AFX_MSG_MAP(CSomeClass)
    ON_WM_DESTROY()
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_SOCKET_EVENT, OnSocketEvent)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSomeClass message handlers

LRESULT CSomeClass::OnSocketEvent(WPARAM wParam, LPARAM lParam)
{
    if (WSAGETSELECTERROR(lParam) != 0)
        return 1;
    
    int nEvent = WSAGETSELECTEVENT(lParam);
    switch (nEvent)
    {
      case FD_ACCEPT: OnSocketAccept(wParam); break;
      case FD_CLOSE: OnSocketClose(wParam); break;
      case FD_READ: OnSocketRead(wParam); break;
      default: break;
    }
    
    return 1;
}

void CSomeClass::OnSocketAccept(WPARAM wParam)
{
    if ((SOCKET)wParam == m_ssLocalHost.GetSocket())
    {
        CxClientSocket xcs; xcs =m_ssLocalHost.Accept(); if (xcs.GetSocket() != INVALID_SOCKET)
        {
            char szIPAddr[MAX_IPV6];
            xcs.GetRemoteHost(szIPAddr);
            
            if (strcmp(szIPAddr, m_ipapRemoteHost.szAddr) == 0)
                m_csRemoteHost = xcs.GetSocket();
       else
            {
                xcs.DisConnect();
                
                CString str;
                str.Format("unknown socket %s disconnect.\n", szIPAddr);
                OutputDebugString(str);
            }
        }
    }    
}

2.回調函數

LRESULT CALLBACK CSomeClass::SocketProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LRESULT lRet = 0;
    CSomeClass* pThis = (CSomeClass*)hwnd;
    if (pThis != 0)
        lRet = pThis->OnSocketEvent(wParam, lParam);

    return lRet;
}

  注意,在使用回調函數時應設置服務端套接字事件通知方式為回調函數,並且設法把this指針傳入設置函數,方便在回調函數中調用成員函數。

MSG msg = {(HWND)this, WM_SOCKET_EVENT};
m_ssRemoteHost.SetWindowMessage(&msg, SocketProc);

 五、停止偵聽客戶端連接請求

void CSomeClass::OnDestroy() 
{
    CStatic::OnDestroy();
    
    // TODO: Add your message handler code here
    TerminateWaitComm();

    m_csRemoteHost.DisConnect();
    m_ssLocalHost.DisListen();
    m_usRemoteHost.Disbind();
}

  至於服務端如何與客戶端交換數據,很簡單:將服務端接受的客戶端連接賦給一個客戶端套接字對象實例,然后讓這個客戶端套接字對象實例在需要處完成數據交換就可以了(客戶端套接字類CxClientSocket如何使用?請查閱往期文章)。

CxClientSocket xcs;
xcs = m_ssLocalHost.Accept();
//  Save the expected socket and disconnect the unexpected socket
m_csRemoteHost = xcs.GetSocket();

  精練的代碼不需要過多解釋,你們懂的。To be continued...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM