MFC疑难注解:CAsyncSocket及CSocket

本文详细解析了MFC中的CAsyncSocket和CSocket,包括它们的工作原理、应用场景及异步机制。并通过实例对比了两种模式的特点,帮助读者更好地理解和选择合适的Socket编程方式。
MFC疑难注解:CAsyncSocket及CSocket
2011年03月30日
  MFC疑难注解:CAsyncSocket及CSocket MFC对SOCKET编程的支持其实是很充分的,然而其文档是语焉不详的。以至于大多数用VC编写的功能稍复杂的网络程序,还是使用API的。故CAsyncSocket及CSocket事实上成为疑难,群众多敬而远之。余好事者也,不忍资源浪费,特为之注解。 一、CAsyncSocket与CSocket的区别 前者是异步通信,后者是同步通信;前者是非阻塞模式,后者是阻塞模式。另外,异步非阻塞模式有时也被称为长连接,同步阻塞模式则被称为短连接。为了更明白地讲清楚两者的区别,举个例子: 设想你是一位体育老师,需要测验100位同学的400米成绩。你当然不会让100位同学一起起跑,因为当同学们返回终点时,你根本来不及掐表记录各位同学的成绩。 如果你每次让一位同学起跑并等待他回到终点你记下成绩后再让下一位起跑,直到所有同学都跑完。恭喜你,你已经掌握了同步阻塞模式。 你设计了一个函数,传入参数是学生号和起跑时间,返回值是到达终点的时间。你调用该函数100次,就能完成这次测验任务。这个函数是同步的,因为只要你调用它,就能得到结果;这个函数也是阻塞的,因为你一旦调用它,就必须等待,直到它给你结果,不能去干其他事情。 如果你一边每隔10秒让一位同学起跑,直到所有同学出发完毕;另一边每有一个同学回到终点就记录成绩,直到所有同学都跑完。恭喜你,你已经掌握了异步非阻塞模式。 你设计了两个函数,其中一个函数记录起跑时间和学生号,该函数你会主动调用100次;另一个函数记录到达时间和学生号,该函数是一个事件驱动的callback函数,当有同学到达终点时,你会被动调用。你主动调用的函数是异步的,因为你调用它,它并不会告诉你结果;这个函数也是非阻塞的,因为你一旦调用它,它就马上返回,你不用等待就可以再次调用它。但仅仅将这个函数调用100次,你并没有完成你的测验任务,你还需要被动等待调用另一个函数100次。 当然,你马上就会意识到,同步阻塞模式的效率明显低于异步非阻塞模式。那么,谁还会使用同步阻塞模式呢? 不错,异步模式效率高,但更麻烦,你一边要记录起跑同学的数据,一边要记录到达同学的数据,而且同学们回到终点的次序与起跑的次序并不相同,所以你还要不停地在你的成绩册上查找学生号。忙乱之中你往往会张冠李戴。 你可能会想出更聪明的办法:你带了很多块秒表,让同学们分组互相测验。恭喜你!你已经掌握了多线程同步模式! 每个拿秒表的同学都可以独立调用你的同步函数,这样既不容易出错,效率也大大提高,只要秒表足够多,同步的效率也能达到甚至超过异步。 可以理解,你现的问题可能是:既然多线程同步既快又好,异步模式还有存在的必要吗? 很遗憾,异步模式依然非常重要,因为在很多情况下,你拿不出很多秒表。你需要通信的对端系统可能只允许你建立一个SOCKET连接,很多金融、电信行业的大型业务系统都如此要求。 现在,你应该已经明白了:CAsyncSocket用于在少量连接时,处理大批量无步骤依赖性的业务。CSocket 用于处理步骤依赖性业务,或在可多连接时配合多线程使用。 二、CAsyncSocket异步机制 当你获得了一个异步连接后,实际上你扫除了发送动作与接收动作之间的依赖性。所以你随时可以发包,也随时可能收到包。发送、接收函数都是异步非阻塞的,顷刻就能返回,所以收发交错进行着,你可以一直工作,保持很高的效率。但是,正因为发送、接收函数都是异步非阻塞的,所以仅调用它们并不能保障发送或接收的完成。例如发送函数Send,调用它可能有4种结果: 1、错误,Send()==SOCKET_ERROR,GetLastError()!=WSAEWOULDBLOCK,这种情况可能由各种网络问题导致,你需要马上决定是放弃本次操作,还是启用某种对策 2、忙,Send()==SOCKET_ERROR,GetLastError()==WSAEWOULDBLOCK,导致这种情况的原因是,你的发送缓冲区已被填满或对方的接受缓冲区已被填满。这种情况你实际上不用马上理睬。因为CAsyncSocket会记得你的Send WSAEWOULDBLOCK了,待发送的数据会写入CAsyncSocket内部的发送缓冲区,并会在不忙的时候自动调用OnSend,发送内部缓冲区里的数据。 3、部分完成,0Create(...); m_pListenSocket->Listen(); ... LRESULT CXxxDlg::OnSocketMsg(WPARAM wParam, LPARAM lParam) { UINT type=(UINT)wParam; switch(type) { case SOCKET_CLNT_ACCEPT: { CSocket* pSocket=new CSocket; if(!m_pListenSocket->Accept(*pSocket)) { delete pSocket; break; } ... } ... } } 2、用于多线程的时候 常看到人说CSocket在子线程中不能用,其实不然。实际情况是: 直接使用CSocket动态创建的对象,将其指针作为参数传递给子线程,则子线程中进行收发等各种操作都没问题。但如果是使用CSocket派生类创建的对象,就要看你重载了哪些方法,假如你仅重载了OnClose,则子线程中你也可以正常收发,但不能Close! 因为CSocket是用内部循环做到同步的,并不依赖各OnXxx,它不需要与CSocketWnd交互。但当你派生并重载OnXxx后,它为了提供消息机制就必须与CSocketWnd交互。当你调用AfxSocketInit时,你的主线程会获得一个访问CSocketWnd的句柄,对CSocketWnd的访问是MFC自动帮你完成的,是被隐藏的。而你自己创建的子线程并不自动具备访问CSocketWnd的机制,所以子线程中需要访问CSocketWnd的操作都会失败。 常看到的解决办法是给子线程传递SOCKET句柄而不是CSocket对象指针,然后在子线程中创建CSocket临时对象并Attach传入的句柄,用完后再Dettach并delete临时对象。俺没有这么干过,估计是因为Attach方法含有获取CSocketWnd句柄的内置功能。 俺的解决方案还是使用自定义消息,比如俺不能在子线程中Close,那么,俺可以给主线程发送一条消息,让主线程的消息处理函数来完成Close,也很方便。 CSocket一般配合多线程使用,只要你想收发数据,你就可以创建一个CSocket对象,并创建一个子线程来进行收发。所以被阻塞的只是子线程,而主线程总是可以随时创建子线程去帮它干活。由于可能同时有很多个CSocket对象在工作,所以你一般还要创建一个列表来储存这些CSocket对象的标识,这样你可能通过在列表中检索标识来区分各个CSocket对象,当然,由于内存地址的唯一性,对象指针本身就可以作为标识。 相对CAsyncSocket而言,CSocket的运作流程更直观也更简单
【EI复现】基于深度强化学习的微能源网能量管理与优化策略研究(Python代码实现)内容概要:本文围绕“基于深度强化学习的微能源网能量管理与优化策略”展开研究,重点利用深度Q网络(DQN)等深度强化学习算法对微能源网中的能量调度进行建模与优化,旨在应对可再生能源出力波动、负荷变化及运行成本等问题。文中结合Python代码实现,构建了包含光伏、储能、负荷等元素的微能源网模型,通过强化学习智能体动态决策能量分配策略,实现经济性、稳定性和能效的多重优化目标,并可能与其他优化算法进行对比分析以验证有效性。研究属于电力系统与人工智能交叉领域,具有较强的工程应用背景和学术参考价值。; 适合人群:具备一定Python编程基础和机器学习基础知识,从事电力系统、能源互联网、智能优化等相关方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①学习如何将深度强化学习应用于微能源网的能量管理;②掌握DQN等算法在实际能源系统调度中的建模与实现方法;③为相关课题研究或项目开发提供代码参考和技术思路。; 阅读建议:建议读者结合提供的Python代码进行实践操作,理解环境建模、状态空间、动作空间及奖励函数的设计逻辑,同时可扩展学习其他强化学习算法在能源系统中的应用。
皮肤烧伤识别作为医学与智能技术交叉的前沿课题,近年来在深度学习方法推动下取得了显著进展。该技术体系借助卷积神经网络等先进模型,实现了对烧伤区域特征的高效提取与分类判别,为临床诊疗决策提供了重要参考依据。本研究项目系统整合了算法设计、数据处理及模型部署等关键环节,形成了一套完整的可操作性方案。 在技术实现层面,首先需要构建具有代表性的烧伤图像数据库,涵盖不同损伤程度及愈合阶段的临床样本。通过对原始图像进行标准化校正、对比度增强等预处理操作,有效提升后续特征学习的稳定性。网络架构设计需充分考虑皮肤病变的区域特性,通过多层卷积与池化操作的组合,逐步抽象出具有判别力的烧伤特征表示。 模型优化过程中采用自适应学习率调整策略,结合交叉熵损失函数与梯度下降算法,确保参数收敛的稳定性。为防止过拟合现象,引入数据扩增技术与正则化约束,增强模型的泛化能力。性能验证阶段采用精确率、召回率等多维度指标,在独立测试集上全面评估模型对不同烧伤类型的识别效能。 经过充分验证的识别系统可集成至医疗诊断平台,通过规范化接口实现与现有医疗设备的无缝对接。实际部署前需进行多中心临床验证,确保系统在不同操作环境下的稳定表现。该技术方案的实施将显著缩短烧伤评估时间,为临床医师提供客观量化的辅助诊断依据,进而优化治疗方案制定流程。 本项目的突出特点在于将理论研究与工程实践有机结合,既包含前沿的深度学习算法探索,又提供了完整的产业化实施路径。通过模块化的设计思路,使得医疗专业人员能够快速掌握核心技术方法,推动智能诊断技术在烧伤外科领域的实际应用。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值