本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!
它是一个异步非阻塞Socket封装类,CAsyncSocket::Create()有一个参数指明了你想要处理哪些Socket事件,你关心的事件被指定以后,这个Socket默认就被用作了异步方式。CAsyncSocket的Create()函数,除了创建了一个SOCKET以外,还创建了个CSocketWnd窗口对象,并使用WSAAsyncSelect()将这个SOCKET与该窗口对象关联,以让该窗口对象处理来自Socket的事件(消息),然而CSocketWnd收到Socket事件之后,只是简单地回调CAsyncSocket::OnReceive()等虚函数。所以CAsyncSocket的派生类,只需要在这些虚函数里添加发送和接收的代码。
中文名

CAsyncSocket
好    处

极大方便
实    质

异步非阻塞Socket封装类
发送和接收

 

1大致的代码为编辑

bool CAsyncSocket::Create( long lEvent ) //参数lEvent是指定你所关心的Socket事件
{
m_hSocket = socket( PF_INET, SOCK_STREAM, 0 ); //创建Socket对象
CSocketWnd* pSockWnd = new CSocketWnd; //创建响应事件的窗口,实际的这个窗口在AfxSockInit()调用时就被创建了。
pSockWnd->Create(...);
WSAAsyncSelect( m_hSocket, pSockWnd->m_hWnd, WM_SOCKET_NOTIFY, lEvent ); //Socket 事件和窗口关联
}
static void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
{
CAsyncSocket Socket;
Socket.Attach( (SOCKET)wParam ); //wParam 就是触发这个事件的Socket的句柄
int nErrorCode = WSAGETSELECTERROR(lParam); //lParam 是错误码与事件码的合成
switch (WSAGETSELECTEVENT(lParam))
{
case FD_READ:
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
pSocket->OnSend(nErrorCode);
break;
case FD_OOB:
pSocket->OnOutOfBandData(nErrorCode);
break;
case FD_ACCEPT:
pSocket->OnAccept(nErrorCode);
break;
case FD_CONNECT:
pSocket->OnConnect(nErrorCode);
break;
case FD_CLOSE:
pSocket->OnClose(nErrorCode);
break;
}
}
CSocketWnd类大致为:
BEGIN_MESSAGE_MAP(CSocketWnd, CWnd)
ON_MESSAGE(WM_SOCKET_NOTIFY, OnSocketNotify)
END_MESSAGE_MAP()
LRESULT CSocketWnd::OnSocketNotify(WPARAM wParam, LPARAM lParam)
{
CAsyncSocket::DoCallBack( wParam, lParam ); //收到Socket事件消息,回调CAsyncSocket的DoCallBack()函数
return 0L;
}
然而,最不容易被初学Socket编程的人理解的,也是本文最要提醒的一点是,客户方在使用CAsyncSocket::Connect()时,往往返回一个WSAEWOULDBLOCK的错误(其它的某些函数调用也如此),实际上这不应该算作一个错误,它是Socket提醒我们,由于你使用了非阻塞Socket方式,所以(连接)操作需要时间,不能瞬间建立。既然如此,我们可以等待呀,等它连接成功为止,于是许多程序员就在调用Connect()之后,Sleep(0),然后不停地用WSAGetLastError()或者CAsyncSocket::GetLastError()查看Socket返回的错误,直到返回成功为止。这是一种错误的做法,断言,你不能达到预期目的。事实上,我们可以在Connect()调用之后等待CAsyncSocket::OnConnect()事件被触发,CAsyncSocket::OnConnect()是要表明Socket要么连接成功了,要么连接彻底失败了。至此,我们在CAsyncSocket::OnConnect()被调用之后就知道是否Socket连接成功了,还是失败了。
类似的,Send()如果返回WSAEWOULDBLOCK错误,我们在OnSend()处等待,Receive()如果返回WSAEWOULDBLOCK错误,我们在OnReceive()处等待,以此类推。

2特别注意编辑

还有一点,也许是个难点,那就是在客户方调用Connect()连接服务方,那么服务方如何Accept(),以建立连接的问题。简单的做法就是在监听的Socket收到OnAccept()时,用一个新的CAsyncSocket对象去建立连接,例如:
void CMySocket::OnAccept( int ErrCode )
{
CMySocket* pSocket = new CMySocket;
Accept( *pSocket );
}
于是,上面的pSocket和客户方建立了连接,以后的通信就是这个pSocket对象去和客户方进行,而监听的Socket仍然继续在监听,一旦又有一个客户方要连接服务方,则上面的OnAccept()又会被调用一次。当然pSocket是和客户方通信的服务方,它不会触发OnAccept()事件,因为它不是监听Socket。

3CAsyncsocket好处编辑

CAsyncSocket类为我们使用Socket提供了极大方便。建立Socket的WSAStartup过程和bind过程被简化成为Create过程,IP地址类型转换主机名和IP地址转换的过程中许多复杂的变量类型都被简化成字符串和整数操作,特别是CAsyncSocket类的异步特点,完全可以替代繁琐的线程操作。MFC提供了大量的类库,我们若能灵活的使用他们,便会大大提高编程的效率。

CAsyncSocket的更多相关文章

  1. [转载]CAsyncSocket及CSocket注解

    MFC疑难注解:CAsyncSocket及CSocket MFC对SOCKET编程的支持其实是很充分的,然而其文档是语焉不详的.以至于大多数用VC编写的功能稍复杂的网络程序,还是使用API的.故CAs ...

  2. CAsyncSocket编程 MFC

    许多时候我们实现网络编程使用的是winsock api函数,虽然这些函数使用起来也很方便,很灵活,但是VC++的MFC类库中提供了CAsyncSocket这样一个套接字类,用它来实现socket编程会 ...

  3. [转] CSocket 和CAsyncSocket类介绍

    微软的MFC把复杂的WinSock API函数封装到类里,这使得编写网络应用程序更容易. CAsyncSocket类逐个封装了WinSock API,为高级网络程序员提供了更加有力而灵活的方法.这个类 ...

  4. CAsyncSocket只传输了一部分数据(UDP),后面是乱码

    void CCAsyncSocketDlg::OnBnClickedBtnSend() { UpdateData(TRUE); TCHAR ipstr[INET_ADDRSTRLEN]; DWORD ...

  5. 使用CAsyncSocket总结

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

  6. CAsyncSocket create创建套接字失败

    解决方法: 在继承CAsyncSocket 类的子类的构造函数中加入以下代码: if (!AfxSocketInit()) AfxMessageBox(IDP_SOCKETS_INIT_FAILED) ...

  7. MFC中CAsyncSocket和CSocket

    原文链接:https://blog.csdn.net/libaineu2004/article/details/40395917 摘要部分重点: 1.CAsyncSocket类逐个封装了WinSock ...

  8. socket API CSocket CAsyncSocket 用法及区别

    要进行网络编程就要和Socket打交道,Socket有同步阻塞方式和异步非阻塞方式两种使用,事实上同步和异步在我们编程的生涯中可能遇到了很多,而Socket也没什么特别.虽然同步好用,不费劲,但不能满 ...

  9. MFC下的网络编程(1)CAsyncSocket进行无连接(UDP)通信

    服务器端发送数据给客户端 先看服务器端: CAsyncSocket m_sockSend;                       //声明一个Socket对象 点击发送数据后,执行下面这些动作 ...

随机推荐

  1. https大势已来?看腾讯专家如何在高并发压测中支持https

    WeTest 导读 用epoll编写一个高并发网络程序是很常见的任务,但在epoll中加入ssl层的支持则是一个不常见的场景.腾讯WeTest服务器压力测产品,在用户反馈中收到了不少支持https协议 ...

  2. 经典shell面试题整理

    一.取出/etc/passwd文件中shell出现的次数 问题:下面是一个/etc/passwd文件的部分内容.题目要求取出shell并统计次数,shell是指后面的/bin/bash,/sbin/n ...

  3. 安卓手机内外SD卡互换

    相信有許多人....有內置sd太小...外置sd(sdcard2或extsd)卻只能放資料.... 一些遊戲或者是影音播放軟體....根本不會去讀外置sd(sdcard2或extsd)..... 記憶 ...

  4. solr单机版的搭建

    一.solr单机版的搭建 1.运行环境 solr 需要运行在一个Servlet容器中,Solr4.10.3要求jdk使用1.7以上,Solr默认提供Jetty(ja),本教va写的Servlet容器程 ...

  5. nodejs远程获取图片

    if(require("http")) {             var http = require("http");             http.g ...

  6. SQL中对日期进行模糊查询的方法

    在我们通过SQL语句对数据库中的数据进行查询时,难免会遇到针对datetime的查询,但是因为一般情况下,输入的时间条件为年月日,所以,这种情况下,我们就要进行一下模糊查询,首先,摒弃一种投机取巧的方 ...

  7. PHP安全设置(转载)

    大家都知道PHP已经是当前最流行的Web应用编程语言了.但是也与其他脚本语言一样,PHP也有几个很危险的安全漏洞.所以在这篇教学文章中,我们将大致看看几个实用的技巧来让你避免一些常见的PHP安全问题. ...

  8. Linux_cloudera-scm-agent: unrecognized service

  9. Web开发-各状态码的意思

    常见的HTTP 1.1状态码以及它们对应的状态信息和含义 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新) 101 Switching Protoc ...

  10. ubuntu安装aircrack-ng/reaver/minidwep-gtk用来跑pin

    按照下面安装方法,可以在Ubuntu 13.04中启动 minidwep.Tested with Ubuntu 13.04 1. Dependencies    Code:    sudo apt-g ...