使用CAsyncSocket总结

简介: 最近想起CAsyncSocket这个类,记得很早以前用过,现在却想不起来怎么用了,翻了翻以前的代码又看了看msdn感觉这个类做简单的异步socket太简单了,几行代码就可以搞定,在此先做个总结。 不管是客户端和服务端都要从CAsyncSocket这个类派生一个类来重载一系列Socket消息事件函数...

最近想起CAsyncSocket这个类,记得很早以前用过,现在却想不起来怎么用了,翻了翻以前的代码又看了看msdn感觉这个类做简单的异步socket太简单了,几行代码就可以搞定,在此先做个总结。

不管是客户端和服务端都要从CAsyncSocket这个类派生一个类来重载一系列Socket消息事件函数比如  CAsyncSocket::OnAccept  CAsyncSocket::OnReceive 等

1.服务端

   1.1首先派生一个类用来监听

class CListenSocket : public CAsyncSocket
{
public:
public:
    CListenSocket();
    virtual ~CListenSocket(); 
    void SetListBox(CListBox * ListBox) {m_ListBox = ListBox;}         //这个ListBox是主窗口里面的一个客户端列表用来显示有几个客户端
    void SetListBoxMsg(CListBox * ListBox) {m_ListBoxMsg = ListBox;}   //这个ListBox是接收客户端消息的
public:
    virtual void OnAccept(int nErrorCode);
    virtual void OnClose(int nErrorCode);
    CClientSocket * GetClientByIndex(int nIndex)  //返回一个已经连接的客户端用来给指定客户端发消息
    { 
        return m_ClientSocketList.GetAt(m_ClientSocketList.FindIndex(nIndex));
    }  
private:
    CList<CClientSocket * > m_ClientSocketList;  //这里要维护一个已经连接的客户端列表,这样服务器可以指定向哪个服务器发消息
    CListBox * m_ListBox;
    CListBox * m_ListBoxMsg;
};

   要响应监视类的Accept事件

void CListenSocket::OnAccept(int nErrorCode)
{
    // TODO: 在此添加专用代码和/或调用基类
    if (nErrorCode == 0)//如果成功
    {
        CClientSocket* pNewClientSocket = new CClientSocket(); //保存一个已经连接的客户端
        BOOL bAccept=Accept(*pNewClientSocket);
        if (bAccept)
        {
            m_ClientSocketList.AddTail(pNewClientSocket);
            pNewClientSocket->SetListBox(m_ListBoxMsg);
            CString SocketName;
            UINT len = 100;
            pNewClientSocket->GetSockName(SocketName,len);
            m_ListBox->AddString(SocketName);           //客户端列表里显示这个已经连接的客户端ip
        }
        else
        {
            DWORD dwErr = GetLastError();
            CString strErr;
            strErr.Format(_T("accept 错误码=%d"),dwErr);
            delete pNewClientSocket;
            AfxMessageBox(strErr);
        }
    }
    CAsyncSocket::OnAccept(nErrorCode);
}

   已经连接客户端对象也是从CAsyncSocket派生来的、

  

class CClientSocket : public CAsyncSocket
{
public:
    CClientSocket();
    virtual ~CClientSocket();
    virtual void OnReceive(int nErrorCode);
    virtual void OnClose(int nErrorCode);
    VOID SetListBox(CListBox * ListBox) {m_ListBox = ListBox;}
    CListBox * m_ListBox;
private:
};

  当服务端收到消息时要响应事件OnReceive

  

void CClientSocket::OnReceive(int nErrorCode)
{
    // TODO: 在此添加专用代码和/或调用基类

    if (nErrorCode == 0)
    {
        char szBuf[1024] = {0};
        INT nReceiveCounts = Receive((VOID*)szBuf,1024);
        if(m_ListBox != NULL)
            m_ListBox->AddString(szBuf);

    }
    

    CAsyncSocket::OnReceive(nErrorCode);
}

   1.2 监听

   

void CMfcSocketDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    if(m_ListenSocket != NULL)
        return ;
    BOOL bInit = AfxSocketInit();
    if(!bInit)
    {
        AfxMessageBox(_T("socket 初始化失败 "));
        return ;
    }
    m_ListenSocket = new CListenSocket();
    BOOL bCreate = m_ListenSocket->Create(10101);
    if(!bCreate)
    {
        AfxMessageBox(_T("创建失败"));
        delete m_ListenSocket;
        m_ListenSocket = NULL;
    }

    BOOL bListen = m_ListenSocket->Listen();
    if(!bListen)
    {
        AfxMessageBox(_T("监听失败!"));
        delete m_ListenSocket;
        m_ListenSocket = NULL;
    }
    m_ListenSocket->SetListBox(&m_ListBoxClientList);  //客户端列表
    m_ListenSocket->SetListBoxMsg(&m_ListBoxRecMsg);   //已经接收的消息
}

 

2.客户端

  2.1 派生一个类用来作为客户端socket

   

#include "afxsock.h"
class CClientSocket :
    public CAsyncSocket
{
public:
    CClientSocket(void);
    virtual ~CClientSocket(void);
    
    virtual void OnReceive(int nErrorCode);
    virtual void OnClose(int nErrorCode);
    virtual  void OnConnect(int nErrorCode );

    void SetListBox(CListBox * ListBox) {m_ListBox = ListBox;}
    CListBox * m_ListBox;
};

  想接收消息就要响应接收消息的事件

  

void CClientSocket::OnReceive(int nErrorCode)
{
    if(nErrorCode == 0)
    {
        CString szBuf;
        INT nReceiveCounts = Receive((VOID*)szBuf.GetBuffer(1000),1000);
        m_ListBox->AddString(szBuf);
    }
}

  2.2 客户端对象的创建和连接 

  

void CMfcSocketClientDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData(TRUE);
    BOOL bInit = AfxSocketInit();
    if(!bInit)
    {
        AfxMessageBox(_T("socket 初始化失败 "));
        return ;
    }
    if(m_ClientSocket == NULL)
    {
        m_ClientSocket = new CClientSocket;
        m_ClientSocket->Create();
    }
    else
    {
        m_ClientSocket->Close();
    }
    m_ClientSocket->Connect(m_Ip,m_Port);
    m_ClientSocket->SetListBox(&m_ListBox);
}

 

上个图片上源码供新手学习

   

 

 

源码:下载

相关文章
explorer.exe 占用cpu或者内存高
本文分享一个explorer.exe 占用cpu或者内存高的案例
explorer.exe 占用cpu或者内存高
|
7月前
|
网络协议 安全 网络安全
Qt 套接字类(QTcpSocket和QUdpSocket)解密:迈向 Qt 网络编程之巅
Qt 套接字类(QTcpSocket和QUdpSocket)解密:迈向 Qt 网络编程之巅
1242 0
|
7月前
C++socket客户端select异步连接发送接收数据
C++socket客户端select异步连接发送接收数据
126 0
TortoiseGit 代码版本回退及返回
TortoiseGit 代码版本回退及返回
511 0
|
C++
【VS】使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题
原文:【VS】使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题 前言 一般来说.NET程序员是不用担心内存分配释放问题的,因为有垃圾收集器(GC)会自动帮你处理。
2662 0