使用CAsyncSocket总结

简介:

最近想起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);
}
复制代码

 

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

   

 

 

源码:下载

相关文章
【PCIe 协议】听说你做 PCIe 很多年,还不知道 PCIe Hierarchy ID 是什么 ???
【PCIe 协议】听说你做 PCIe 很多年,还不知道 PCIe Hierarchy ID 是什么 ???
960 0
【PCIe 协议】听说你做 PCIe 很多年,还不知道 PCIe Hierarchy ID 是什么 ???
|
关系型数据库 MySQL Linux
Centos7 yum如何下载离线安装包?(详解)
相信大家也遇到过这种问题,在没有外网的情况下,想安装一个服务却安装不了,这期我就教大家如何如何下载离线安装包,在内网中使用;
2460 0
Centos7 yum如何下载离线安装包?(详解)
|
5月前
|
前端开发 IDE Java
Spring MVC 中因导入错误的 Model 类报错问题解析
在 Spring MVC 或 Spring Boot 开发中,若导入错误的 `Model` 类(如 `ch.qos.logback.core.model.Model`),会导致无法解析 `addAttribute` 方法的错误。正确类应为 `org.springframework.ui.Model`。此问题通常因 IDE 自动导入错误类引起。解决方法包括:删除错误导入、添加正确包路径、验证依赖及清理缓存。确保代码中正确使用 Spring 提供的 `Model` 接口以实现前后端数据传递。
158 0
|
机器学习/深度学习 TensorFlow 算法框架/工具
深度学习在图像识别中的应用:一个实战案例
【8月更文挑战第1天】 本文将通过一个实际案例,深入探讨深度学习在图像识别领域的应用。我们将介绍如何利用卷积神经网络(CNN)进行图像分类,并展示一个简单的代码示例。通过本文,您将了解到深度学习技术在解决实际问题中的潜力和挑战。
|
JavaScript 前端开发 搜索推荐
ECharts词云图(案例一)+配置项详解
ECharts,百度的JavaScript图表库,支持词云图(自5.0版起),借助`echarts-wordcloud`插件。配置词云图涉及`tooltip`(如显示、颜色、边框等)和`series`(类型、形状、大小范围等)。示例代码展示了如何在HTML中引入依赖并配置词云图,包括数据、形状、大小、颜色等。完整代码和依赖可下载。调整这些配置可创建个性化词云图。参阅官方文档获取不同版本详情。
3518 4
 ECharts词云图(案例一)+配置项详解
|
存储 传感器 算法
【Arduino环境下驱动合宙esp32c3单片机基本外设】
【Arduino环境下驱动合宙esp32c3单片机基本外设】
930 1
|
存储 缓存 数据库
InfluxDB性能优化:写入与查询调优
【4月更文挑战第30天】本文探讨了InfluxDB的性能优化,主要分为写入和查询调优。写入优化包括批量写入、调整写入缓冲区、数据压缩、shard配置优化和使用HTTP/2协议。查询优化涉及索引优化、查询语句调整、缓存管理、分区与分片策略及并发控制。根据实际需求应用这些策略,可有效提升InfluxDB的性能。
2869 1
|
机器学习/深度学习 算法
理解并应用机器学习算法:决策树
【5月更文挑战第12天】决策树是直观的分类与回归机器学习算法,通过树状结构模拟决策过程。每个内部节点代表特征属性,分支代表属性取值,叶子节点代表类别。构建过程包括特征选择(如信息增益、基尼指数等)、决策树生成和剪枝(预剪枝和后剪枝)以防止过拟合。广泛应用在信贷风险评估、医疗诊断等领域。理解并掌握决策树有助于解决实际问题。
|
应用服务中间件 Linux nginx
CentOS7创建nginx服务并配置开机自启
CentOS7创建nginx服务并配置开机自启
396 0
PCIe 均衡技术介绍(概要)
PCIe 均衡技术介绍(概要)
2331 1
PCIe 均衡技术介绍(概要)