当前位置:首页 > 智能硬件 > 智能硬件
[导读]摘要 介绍了在TCP/IP网络中WinSock网络编程的基本流程及WinSock编程常用的两种类,集中探讨了MFC提供的异步非阻塞类CAsyncSocket的特点,包括类对象的创建、异步选择机制以及对网络事件的响应。以及采用CAsyncSocke

摘要 介绍了在TCP/IP网络中WinSock网络编程的基本流程及WinSock编程常用的两种类,集中探讨了MFC提供的异步非阻塞类CAsyncSocket的特点,包括类对象的创建、异步选择机制以及对网络事件的响应。以及采用CAsyncSocket类进行网络通信的通信流程,并结合实际开发经验,介绍了使用CAsyncSocket类进行网络编程的基本框架。通过使用可大大提高编程的效率。
关键词 TCP/IP;WinSock;异步通讯;非阻塞;CasyncSocket

    随着Internet技术的应用和普及,多数应用程序都是运行在网络环境下,这就要求程序员能在应用最广泛的Windows操作系统上开发网络应用程序。文中介绍了WinSock编程的基本流程,并利用MFC提供的CAsyncSocket类,结合在VS2008环境下实际的开发经验,介绍了Windows平台下基于TCP的异步网络编程的相关知识。

1 WinSock编程的基本流程
    在TCP/IP网络中,两个进程间相互作用的主要模式是客户机/服务器模式,该模式的建立基于以下两点:(1)非对等作用。(2)通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式。面向连接(TCP)的典型过程如图1所示。



2 CAsyncSocket类的简单介绍
    微软公司开发的Visual C++是Windows平台下强有力的开发工具。VC++对网络编程的支持有socket支持,WinInet支持,MAPI和ISAPl支持等,其中Windows Sockets API是TCP/IP网络环境下开发最为通用的API。为简化WinSock网络编程,使用户专注于应用程序的算法设计,Microsoft的基本类库(Microsoft Foundation Class,MFC)提供了两个用于Winsock编程的类,分别是CAsyncSocket类和CSocket类:这两个类在不同程度上对WinSock API函数进行了封装,具有直接调用Sockets API的灵活性。CAsyncSocket类是从CObject类派生出来的,在很低的级别上一对一封装了Windows Sockets API,因此具有直接调用Socket API的灵活性,可以使用面向对象的方式进行Socket编程,CAsync Soc ket类可以方便地调用其他MFC对象,处理多个网络协议。与CSocket类相比,CAsyncSocket类有以下特点。
2.1 CAsyncSocket类对象的创建
    CAsyncSocket是一个异步非阻塞Socket封装类,CAsvncSocket的Create()函数,除创建了一个Socket以外,CAsyncSocket::Create()的参数IEvent指明了想要处理的Socket事件,关心的事件被指定以后,这个Socket默认就被用作了异步方式。CAsyncSocket还创建了个CSoc ketWnd窗口对象,并使用WSAAsyncSelect()将这个SOCKET与该窗口对象关联,以使该窗口对象处理来自Socket的事件(消息),然而CSocket Wnd收到Socket事件之后,只是简单地回调CAsyncSocket::OnReceive()等虚函数。所以CAsyncSocket的派生类,只需在这些虚函数里添加发送和接收的代码,除此外Create()函数还调用Bind()函数将Socket对象与指定的地址绑定。其函数原型为:
    BOOL CAsyncSocket::Create(UINT nSocketPort=0,intnSocketType=SOCK_STREAM,long lEvent=FD_READ|FD_WRITE|FD_OOB|FD_ACC EPT|FD_CONNECT|FD_CLOSE,LPCTSTR lpszSocketAddress=NULL);
    在重载函数中都有一个参数nErrorCode,为零则表示正常完成,非零则表示错误。通过int CAsyncSocket::GetLastError()可以得到错误值。参数nSocketPort为使用的端口号,为零则表示由系统自动选择,通常在客户端都使用这个选择。参数nSocketType为使用的协议族,SOCK_STREAM表明使用有连接的服务,SOCK_DGRAM表明使用无连接的数据报服务。参数lpszSocketAddress指定了IP地址,可以使用点分法表示如192.168.0.28,也可以使用默认值,此时函数将默认绑定本机IP地址。
2.2 CAsyncSocket类的异步选择机制
    在网络通讯中,由于网络拥挤或数据量大的原因,数据的收发不能立刻完成,收发数据的函数因此不能返回,从而出现阻塞现象。Win Sock对有可能阻塞的函数提供了两种处理方式:阻塞和非阻塞方式。在阻塞方式下,收发数据的函数在被调用后一直要到传送完毕或者出错才能返回。对于非阻塞方式,函数被调用后立即返回,传送完成后由WinSock给程序发一个事先约定好的消息。使用Windows Sockets实现Windows网络程序设计的关键就是它提供了对网络事件基于消息的异步存取,用于注册应用程序感兴趣的网络事件。Winsock过WSAAsyncse lect()动地设置套接字处于非阻塞方式,注册一个或多个网络事件。当被提名的网络事件发生时,Windows应用程序的窗口函数将收到一个消息,消息附带的参数指示被提名过的某一网络事件。WSAAsyncSelect的原型如下:
    int PASCAL FAR WSAAsyncSelect(SOCTET s,HWND hWnd,unsignedint wMsg,long lEvent)它请求Windows Sockets DLL在检测到套接字上发生的网络事件时,向窗口hWnd发送一个消息。MFC在实现CAsyncSocket类时,定义了一个内部类CSocket Wnd,当使用Create函数产生Socket句柄时,就Attach这个Socket到一个窗口上,并且CAsyncSocket的DoCallBack函数为该窗口的回调函数。在此函数内根据不同的消息参数,响应各个网络事件。
2.3 CAsyncSocket对网络事件的响应
    在理解以上机制后,再了解一下CAsyncSocket的通信流程。
    CAsvncSocket在AsyncSelect函数中调用WSAAsyncselect函数注册感兴趣的网络事件。这样,当一个网络事件发生时,经过MFC的消息循环,就可以由CAsyncSocket的DoCAllBack函数按事件的类型:FD_READ,FD_WRITE,FD_ACCEPT,FD_CONNECT和FD_CLOSE来分别调用OnReceive(),OnSend(),OnAccept(),OnConnect()和OnClose()函数。具体的对应关系如表1所示。



3 使用CAsyncSocket类的通讯流程
    在理解了上述的机制后,CAsyncSocket的通信流程:客户方在使用CAsyncSocket::Connect()时,往往返回一个WSAEWOULDBLOCK的错误,实际上这不应该算作一个错误,它是Socket的提醒,由于使用了非阻塞Socket方式,所以操作需要时间,不能瞬间建立。那么可以等待,等待连接成功,于是许多程序员就在调用Connect()之后,Sleep(0),然后不停地用WSAGetLastError()或者CAsyncSocket::GetLast Error()查看Socket返回的错误,直到返回成功为止。这是一种错误的做法,断言不能达到预期目的。事实上,可以在Connect()调用之后等待CAsyncSocket::OnConnect()事件被触发。类似地,Send()如果返回WSAEWOULDBLOCK错误,在OnSend()处等待,Receive()如果返回WSAE WOULDBLOCK错误,则在OnReceive()处等待,具体的内部通信流程如图2所示。



4 使用CAsyncSocket编程的程序框架
    在进行C/S编程之前,需在定义应用程序行为的文件030 303.cpp中的Initlnstance()函数里调用AfxSocketInit()函数来初始化Wind ows Sockets。
    (1)服务器端
    以public的方式从CAsyncSocket类派生新类CServerSock,并重载OnAccept、OnReceive、OnSend函数。
    函数重载完成后,在主窗口构造新的CServeSock对象,用来监听来自客户机的连接,添加代码如下:
    CServeSock m_ListenSock;//m_ListenSock为监听套接字
    m_ListenSock.Create(m_Port,SOCK_STREAM,FD ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)
    m_ListenSock→Listen(int nConnectionBacklog=5);
    函数Send()的参数说明:
    nconnectionBacklog:等待连接的最大队列长度。
    此时服务器开始监听来自客户机的连接请求。
    (2)客户机端
    以public的方式从CAsyncSocket类派生新类CClientSock,与服务器端类似,重载OnReceive()、OnSend()函数。
    已经搭建好使用CAsyncSocket类实现基于TCP协议的异步网络通讯的框架,具体的应用程序可以在此基础上进行丰富与修改。

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

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

将您的树莓派Pico变成带有触摸屏界面的USB-HID设备!在这个项目中,我们将在Arduino IDE中设置编程环境,为3.5”Pico Touch LCD屏蔽配置库,测试基本功能,创建简单的按钮(用于复制和粘贴),显...

关键字: 树莓派 触摸屏 LCD Windows

这是一个演示,展示了我正在开发的自定义gpt,并在r/arduino上发布了一系列关于它的内容。它可以很容易地与您的任何项目在您的标准工作。/ Arduino文件夹。它是多平台的,所以无论你运行的是Windows、mac...

关键字: Windows macOS Linux Arduino项目管理器

在这里,我们在相当旧的Latte Panda V1单板计算机上启动了Batocera,该计算机于2015年发布,拥有英特尔Atom x5-Z8350四核处理器和4GB DDR3L RAM。这个处理器在当时对于SBC来说是...

关键字: 单板计算机 Windows x86处理器

Amazon Q Developer是首个基于生成式AI的助手,旨在加速Windows.NET、VMware和大型机工作负载的迁移和现代化,缩短转型时间并降低成本 北京2024年12月23日 /美通社/ -- ...

关键字: DEVELOPER 亚马逊 NET Windows

Linux上的大多数软件都是开源的,开发者在全球范围内对其进行了维护,并为之作出了贡献。这就意味着,用户可以在更大程度上,获得更大的自由度,更多的选择。而且,在 Windows中,很多先进的特性和专门的软件都是需要许可的...

关键字: Linux Windows

7月21日消息,据国外媒体报道,近日全球范围内Windows设备出现大规模瘫痪事件,不仅导致飞机停飞、医院服务中断,更暴露了全球经济对微软的深度依赖。

关键字: Windows

FTDI Chip高速USB 2.0系列FT4232HA是业界首款USB2.0高速转四通道UART或双通道MPSSE的车规级芯片。

关键字: USB2.0 车规级芯片 Windows

业内消息,近日微软和高通公司在微软 Build 2024 会议中宣布,将为开发者提供 Windows 版骁龙开发套件(Snapdragon Dev Kit for Windows),用于制作与骁龙X芯片配合使用的 Cop...

关键字: 高通 Windows 开发者 骁龙 开发套件

好用、高效的多合一传感器开发工具,支持给新一代高科技 MEMS 传感器产品开发应用软件

关键字: 传感器 Windows MacOS

双系统将是下述内容的主要介绍对象,通过这篇文章,小编希望大家可以对双系统的相关情况以及信息有所认识和了解,详细内容如下。

关键字: 双系统 Windows Linux
关闭