亚洲av色香蕉一区二区三区,十四以下岁毛片带血a级,亚洲 校园 欧美 国产 另类,亚洲av日韩av一区谷露,色欲av无码一区二区三区

  • 相關(guān)軟件
    >扔掉Socket實現(xiàn)網(wǎng)絡(luò)編程 創(chuàng)建者:webmaster 更新時間:2005-07-02 01:24

    隨著計算機網(wǎng)絡(luò)化的深入,計算機網(wǎng)絡(luò)編程在程序設(shè)計的過程中變得日益重要。許多文章都曾經(jīng)介紹過用VC++進行Socket編程的方法。但由于都是直接利用動態(tài)連接庫wsock32.dll進行操作,實現(xiàn)比較繁瑣。其實,VC++的MFC類庫中提供了CAsyncSocket這樣一個套接字類,用它來實現(xiàn)Socket編程,是非常方便的。

      客戶端

      創(chuàng)建一個Dialog Based項目:CSockClient。設(shè)計一對話框,增加ID_Connect(連接)、ID_Send(發(fā)送)、ID_Exit(關(guān)閉)按鈕,增加ListBox控件IDC_LISTMSG和Edit控件IDC_EDITMSG,并按下表在ClassWizard中為CCSockClientDlg類添加變量。

      Control ID Type Member
      IDC_EDITMSG CEdit m_MSG
      IDC_LISTMSG ClistBox m_MSGS

      在MySock.ccp中添加以下代碼:

      #include "CSockClient.h"
      #include "CSockClientDlg.h"

      在MySock.h中添加以下代碼:

      public:
    BOOL m_bConnected;
    UINT m_nLength;
    char m_szBuffer[4096];
    在MySock.ccp中重載各函數(shù)
    MySock::MySock()
    { m_nLength=0;
    memset(m_szBuffer,0,sizeof(m_szBuffer));
    m_bConnected=FALSE;}
    MySock::~MySock()
    { //關(guān)閉套接字
    if(m_hSocket!=INVALID_SOCKET)
    Close(); }
    void MySock::OnReceive(int nErrorCode)
    { m_nLength=Receive(m_szBuffer,sizeof(m_szBuffer),0);
    //下面兩行代碼用來獲取對話框指針
    CCSockClientApp* pApp=(CCSockClientApp*)AfxGetApp();
    CCSockClientDlg* pDlg=(CCSockClientDlg*)pApp- >m_pMainWnd;
    pDlg- >m_MSGS.InsertString(0,m_szBuffer);
    memset(m_szBuffer,0,sizeof(m_szBuffer));
    CAsyncSocket::OnReceive(nErrorCode);}
    void MySock::OnSend(int nErrorCode)
    { Send(m_szBuffer,m_nLength,0);
    m_nLength=0;
    memset(m_szBuffer,0,sizeof(m_szBuffer));
    //繼續(xù)提請一個“讀”的網(wǎng)絡(luò)事件,接收Server消息
    AsyncSelect(FD_READ);
    CAsyncSocket::OnSend(nErrorCode);}
    void MySock::OnConnect(int nErrorCode)
    { if (nErrorCode==0)
    { m_bConnected=TRUE;
    CCSockClientApp* pApp=(CCSockClientApp*)AfxGetApp();
    CCSockClientDlg* pDlg=(CCSockClientDlg*)pApp- >m_pMainWnd;
    memcpy(m_szBuffer,"Connected to ",13);
    strncat(m_szBuffer,pDlg- >m_szServerAdr,
    sizeof(pDlg- >m_szServerAdr));
    pDlg- >m_MSGS.InsertString(0,m_szBuffer);
    AsyncSelect(FD_READ);}//提請一個“讀”的網(wǎng)絡(luò)事件,準備接收
    CAsyncSocket::OnConnect(nErrorCode); }


      建一對話框IDD_Addr,用來輸入IP地址和Port;增加兩個Edit控件:IDC_Addr、IDC_Port按下表在ClassWizard中為CAddrDlg類添加變量。

      Control ID Type Member
    IDC_Addr CString m_Addr
    IDC_Port Int m_Port
    在CSockClientDlg.ccp中添加代碼:
    #include "AddrDlg.h"
    protected:
    int TryCount;
    MySock m_clientSocket;
    UINT m_szPort;
    public:
    char m_szServerAdr[256];

      雙擊IDD_CSOCKCLIENT_DIALOG對話框中的“連接”按鈕,添加以下代碼:

    m_clientSocket.ShutDown(2);
    m_clientSocket.m_hSocket=INVALID_SOCKET;
    m_clientSocket.m_bConnected=FALSE;
    CAddrDlg m_Dlg;
    m_Dlg.m_Port=1088;//默認端口1088
    if (m_Dlg.DoModal()==IDOK && !m_Dlg.m_Addr.IsEmpty())
    { memcpy(m_szServerAdr,m_Dlg.m_Addr,sizeof(m_szServerAdr));
    m_szPort=m_Dlg.m_Port;
    SetTimer(1,1000,NULL);//建立計時器,每1秒嘗試連接一次
    TryCount=0;}
    添加Windows消息WM_TIMER響應(yīng)函數(shù)OnTimer
    void CCSockClientDlg::OnTimer(UINT nIDEvent)
    { if (m_clientSocket.m_hSocket==INVALID_SOCKET)
    { BOOL bFlag=m_clientSocket.Create(0,SOCK_STREAM,FD_CONNECT);
    if(!bFlag)
    { AfxMessageBox("Socket Error!");
    m_clientSocket.Close();
    PostQuitMessage(0);
    return;}}
    m_clientSocket.Connect(m_szServerAdr,m_szPort);
    TryCount++;
    if (TryCount >=10 || m_clientSocket.m_bConnected)
    { KillTimer(1);
    if (TryCount >=10)
    AfxMessageBox("Connect Failed!");
    return;}
    CDialog::OnTimer(nIDEvent);}

      雙擊IDD_CSOCKCLIENT_DIALOG對話框中的“發(fā)送”按鈕,添加以下代碼:

      void CCSockClientDlg::OnSend()
    {if (m_clientSocket.m_bConnected)
    { m_clientSocket.m_nLength=m_MSG.GetWindowText
    (m_clientSocket.m_szBuffer, sizeof(m_clientSocket.m_szBuffer));
    m_clientSocket.AsyncSelect(FD_WRITE);
    m_MSG.SetWindowText("");}}
    雙擊IDD_CSOCKCLIENT_DIALOG對話框中的“關(guān)閉”按鈕,添加以下代碼:
    void CCSockClientDlg::OnExit()
    { m_clientSocket.ShutDown(2); //關(guān)閉Socket
    EndDialog(0);}

      運行此項目,連接時輸入主機名或IP均可,CAsyncSocket類會自動處理。



      服務(wù)端

      Server端的編程與Client端的類似,下面主要介紹他的Listen及Accept函數(shù)。建立一個CNewSocket類,重載CAsyncSocket類的OnReceive、OnSend函數(shù),如何進行信息的顯示和發(fā)送可以參考Client程序。本例中采用將收到信息原封不動發(fā)回的方法來實現(xiàn)Echo功能,代碼如下:

      CNewSocket::OnReceive(int nErrorCOde)
    { m_nLength=Receive(m_szBuffer,sizeof(m_szBuffer),0);
    AsyncSelect(FD_WRITE);}// 直接轉(zhuǎn)發(fā)消息
    CNewSocket::OnSend(int nErrorCode)
    { Send(m_szBuffer,m_nLength,0);}

      建立一個CMyServerSocket類,重載CAsyncSocket類的OnAccept函數(shù)代碼如下:

      在MyServerSocket.h中聲明變量

    public::
    CNewSocket* m_pSocket;
    void CMyServerSocket::OnAccept(int nErrorCode)
    { CNewSocket* pSocket = new CNewSocket();
    if (Accept(*pSocket))
    { pSocket- >AsyncSelect(FD_READ);
    m_pSocket=pSocket;}else
    delete pSocket;}

      為對話框添加一個“偵聽”按鈕,添加如下代碼:

      在CsockServerDlg.ccp中聲明變量
    public:
    CMyServerSocket m_srvrSocket;
    void CCSockServerDlg::OnListen()
    { if (m_srvrSocket.m_hSocket==INVALID_SOCKET)
    { BOOL bFlag=m_srvrSocket.Create
    (UserPort,SOCK_STREAM,F(xiàn)D_ACCEPT);
    if (!bFlag)
    { AfxMessageBox(“Socket Error!”);
    M_srvrSocket.Close();
    PostQuitMessage(0);
    Return;}}
    if (!m_srvrSocket。Listen(1))
    { int nErrorCode = m_srvrSocket.GetLastError();
    if (nError!=WSAEWOULDBLOCK)
    { AfxMessageBox(“Socket Error!”);
    M_srvrSocket.Close();
    PostQuitMessage(0);
    Return;}}}

      CAsyncSocket類為我們使用Socket提供了極大方便。建立Socket的WSAStartup過程和bind過程被簡化成為Create過程,IP地址類型轉(zhuǎn)換、主機名和IP地址轉(zhuǎn)換的過程中許多復(fù)雜的變量類型都被簡化成字符串和整數(shù)操作,特別是CAsyncSocket類的異步特點,完全可以替代繁瑣的線程操作。MFC提供了大量的類庫,我們?nèi)裟莒`活的使用他們,便會大大提高編程的效率。

    相關(guān)文章
    本頁查看次數(shù):