使用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或者内存高
|
11月前
|
存储 运维 安全
|
存储 人工智能 自然语言处理
利用AI技术实现智能客服系统
【8月更文挑战第27天】本文将介绍如何利用人工智能(AI)技术构建一个智能客服系统,以提高客户服务效率和质量。我们将从需求分析、系统设计、功能实现等方面进行详细阐述,并通过实际代码示例展示如何实现一个简单的智能客服系统。
|
Prometheus Cloud Native
Mac下安装 Prometheus+Grafana
Mac下安装 Prometheus+Grafana
769 0
CSDN--MD编辑器学习--图片插入尺寸和对齐方式
CSDN--MD编辑器学习--图片插入尺寸和对齐方式
326 0
C++socket客户端select异步连接发送接收数据
C++socket客户端select异步连接发送接收数据
286 0
|
存储 小程序 定位技术
微信小程序获取用户信息流程
微信小程序获取用户信息流程
|
运维 JavaScript 前端开发
海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js
随着现代化产品研发的不断推进,我们会发现,几乎每个产品线都会包含功能各异的服务,而且服务与服务之间存在也会存在着错综复杂的依赖和被依赖关系,这就会带来一个世界性难题,项目部署的时候需要运维来手动配制服务之间通信的协议和地址,稍有不慎就会导致服务异常,同时如果服务器因为坏道或者其他原因导致更换物理机,重新部署新环境的成本也会非常之高。因此,我们就会寄希望于Docker这种的容器技术可以让我们构建产品所需要的所有的服务能够迅速快捷的重新部署,并且可以根据需求做横向扩展,且能够保证稳定的容灾性,在出现问题的时候可以利用守护进程自动重启或者启动容灾备份。
海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js
|
Web App开发 移动开发 安全
「趣学前端」关于iframe跨域通信
用技术实现梦想,用梦想打开创意之门。之前开发遇到了iframe跨域通信的问题,今天分享一下解决方案,顺便总结一波知识点。
1320 1
「趣学前端」关于iframe跨域通信