VC网络通信API概览

系统 1655 0

1 WinSock API

Windows Sockets 是在 Windows 环境下使用的一套网络编程规范,常常简称为 Winsock

WinSock 主要是基于 socket 来开发基于 TCP/IP 模型中各层的服务器端与客户端程序。可使用 RAW SOCKET API (原始套接字)开发低层协议的程序,当然这需要了解协议的报文格式。

1.1 Windows Sockets API

参考《 WinSock 编程基础 》中的 Windows Sockets 规范。

1.2 Winsock API 函数的分类

Winsock 规范中把 Winsock API 函数集分为与 BSD Socket( 用在 Unix ) 相兼容的基本函数、网络数据信息检索函数和 Windows 专用扩展函数三类。

参考《 WinSock 编程基础 》中的套接字 API 概览。

2 CAsyncSocket/CSocket

2.1 MFC Winsock API 的封装( Windows Sockets: Using Class CAsyncSocket

CAsyncSocket 对象表示一个 Windows Socket-- 一个网络通信的端点。 CAsyncSocket 类封装了 Windows 套接字 API ,对想使用与 MFC 连接的 Windows 套接字的程序员提供了一个面向对象的抽象化概念。它是基于暗窗口的 WSAAsyncSelcet 异步 I/O 模型。所谓 暗窗口 是指委托处理网络事件消息的窗口,即 "Socket Notification Sink" 。由于暗窗口只是用来在后台做消息处理,故其风格、尺寸都为零,隐而不显。

应用此类,需处理块、字节顺序(大小端)以及 Unicode 和多字符集( MBCS )的问题。如果想要一个更方便的处理这些问题的接口,参阅 CSocket 类。

CAsyncsocket 对象相比, CSocket 对象代表了 Windows Sockets API 的更高一级的抽象化。 CSocket 与类 CSocketFile CArchive 一起来管理对数据的发送和接收。

CAsyncSocket & CSocket

2.2 CAsyncsocket

声明一个 CAsyncSocket 对象后,需调用 Create 成员函数进行具体套接字的创建: CAsyncSocket :: Create à CAsyncSocket :: Socket à CAsyncSocket :: AttachHandle / CAsyncSocket :: AsyncSelect

CAsyncSocket :: AttachHandle 完成 MFC 对象 CAsyncSocket SOCKET 内核对象(句柄)的附加委托。

使用 CAsyncSocket 的线程在创建第一个对象时, _AFX_SOCK_THREAD_STATE :: m_pmapSocketHandle -> IsEmpty () == TRUE, 将创建一个暗窗口( CSocketWnd 对象)并记录在线程套接字状态管理模块的 m_hSocketWindow 字段中( _AFX_SOCK_THREAD_STATE :: m_hSocketWindow )。

CAsyncSocket :: AsyncSelect 中,调用 WSAAsyncSelect ( m_hSocket , pState -> m_hSocketWindow , WM_SOCKET_NOTIFY , lEvent )

以后该线程的所有 CAsyncSocket 对象的网络事件均以消息 WM_SOCKET_NOTIFY 发送给 _AFX_SOCK_THREAD_STATE :: m_hSocketWindow

暗窗口 CSocketWnd 接收 WM_SOCKET_NOTIFY 消息,消息处理函数 OnSocketNotify 被调用 ON_MESSAGE ( WM_SOCKET_NOTIFY , OnSocketNotify )

WM_SOCKET_NOTIFY 消息的 wParam 参数为对应发生该事件的套接字句柄, lParam 参数的高字位 ( 一般用 WSAGETSELECTERROR 宏取得 HIWORD) 包含出错码, lParam 参数的低字位 ( 一般用 WSAGETSELECTEVENT 宏取得 LOWORD) 则标识了网络事件代码 (FD_XXX) 。一般先检查高位,再检查低位进行网络事件的处理。

OnSocketNotify 函数回调 CAsyncSocket :: DoCallBack DoCallBack 调用事件处理函数,如 OnRead OnWrite 等。 OnRead OnWrite CAsyncSocket 中为空,用户一般需要重载虚函数 OnRead OnWrite ,调用 Receive Send 进行接发处理。 Receive Send 只是对 recv send 的简单调用,它们都是可重载的虚函数。

2.3 CSocket

CSocket 类是从 CAsyncsocket 派生的一个 同步阻塞 Socket 的封装类, CSocket 类的诸如 Send() Receive() 在收到 WSAEWOULDBLOCK“ 错误 时,不是如 CAsyncSocket 那样立即返回,而是 进入 PumpMessages() 消息循环 PumpMessages() 直到有指定事件( uStopFlag == FD_* )发生才返回,在 2 秒( CSocket :: m_nTimeOut 期间,如果线程取到了任一窗口的 WM_PAINT 消息,则刷新相应窗口。这样异步的 CAsyncSocket ,到了派生类 CSocket ,就变成同步的了。

2.4 多线程环境下的 CAsyncSocket/CSocket

CAsyncSocket/CSocket 不是线程安全的,典型的在一个线程里调用了 CSocket 的成员函数,之后启动一个线程,在另一线程中对 CSocket 对象调用成员函数会失败,提示 SOCKET 相关的窗口不存在。其原因在于消息循环是和窗口相关的,而窗口又是线程相关的。具体涉及到 SOCKET 状态 _AFX_SOCK_STATE SOCKET 线程模块状态 _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE )。

CSocket 一般配合多线程使用,只要你想收发数据,你就可以创建一个 CSocket 对象,并创建一个子线程来进行收发。同步 + 多线程 异步。但是大规模并发通信时,由于 Windows 消息泵本省的局限性, WAsyncSelect 异步模型可能遭遇瓶颈。

最后,别忘了使用 MFC WinSock CAsyncSocket/CSocket 的线程需要调用 AfxSocketInit 初始化 WinSock 库。一般在 MFC 程序的 CWinApp :: InitInstance () 中调用 AfxSocketInit

源码参考 <AFXSOCK.H> <AFXSOCK.INL> <SOCKCORE.CPP>

// AFXSOCK.H

#include <winsock.h>

#pragma comment(lib, "wsock32.lib")

/////////////////////////////////////////////////////////////////

// AFXSOCK - MFC support for Windows Sockets

// CSocketWnd -- internal use only Implementation for sockets notification callbacks.

class CSocketWnd : public CWnd

// Async Socket implementation and base class for Synchronous Socket

class CAsyncSocket : public CObject

// Synchronous Socket

class CSocket : public CAsyncSocket

// Used with CSocket and CArchive for streaming objects on sockets.

class CSocketFile : public CFile

3 WinInet API

WinInet API 主要是开发基于 TCP/IP 模型中的应用层 客户端 程序。

WinInet (「 Windows Internet 」) API 是一个高阶函数集,帮助程序写作者使用三个常见的 Internet 协议:用于 World Wide Web 全球信息网的超文字传输协议( HTTP Hypertext Transfer Protocol )、文件传输协议( FTP File Transfer Protocol )和另一个称为 Gopher 的文件传输协议。

WinInet API 由动态链接库 wininet.dll 提供支持。

// Internet Extensions for Win32

#include <wininet.h>

#pragma comment (lib, "wininet.lib")

LoadLibrary ("C://WINDOWS//system32//wininet.dll");

WinInet 函数的语法与常用的 Windows 文件函数的语法类似,这使得使用这些协议就像使用本地磁盘驱动器上的文件一样容易。

MFC WinInet API 的封装( MFC Classes for Creating Internet Client Applications

MSDN 关键字 WinInet, programming/ WinInet, classes

MFC provides the following classes and global functions for writing Internet client applications . Indentation indicates a class is derived from the unindented class above it. CGopherFile and CHttpFile derive from CInternetFile , for example.

Classes:

CInternetSession

CInternetConnection

CFtpConnection

CGopherConnection

CHttpConnection

CInternetFile

CGopherFile

CHttpFile

CFileFind

CFtpFileFind

CGopherFileFind

CGopherLocator

CInternetException

Global functions:

AfxParseURL

AfxGetInternetHandleType

AfxThrowInternetException

源码参考 <AFXINET.H> <AFXINET.INL> <INET.CPP>

// AFXINET.H

#include <wininet.h>

#pragma comment(lib, "wininet.lib")

// Global Functions

AfxParseURL ();

AfxParseURLEx ();

CHtmlView

class CHtmlView : public CFormView

CHtmlView 类在文档 / 视图结构的应用程序中提供 WebBrowser 控件的功能。 WebBrowser 控件是客户可浏览网址以及本地文件和网络文件的窗口。 WebBrowser 控件支持超级链接、统一资源定位符( URL )导航器并维护一张历史列表,核心接口是 IWebBrowser2 ,它是 Internet Explorer 的核心。

源码参考 <AFXHTML.H> <AFXHTML.INL> <VIEWHTML.CPP>

4.ISAPI

ISAPI Internet Server Application Program Interface 服务器 应用程序接口)的简写,是微软提供的一套面向 Internet 服务的 API 接口,它能实现 CGI Common Gateway Interface ,公共网关接口)能提供的全部功能,并在此基础上进行了扩展,如提供了过滤器应用程序接口。 ISAPI 的工作原理和 CGI 大体上是相同的,都是通过交互式主页取得用户输入信息,然后交服务器后台处理。

ISAPI 应用的 DLL 不仅可以象 CGI 程序一样被用户请求激活,还可以被系统预先激活来监视用户输入;对于被用户激活的 DLL ,在处理完一个用户请求后不会马上消失,而是继续驻留在内存中等待处理别的用户输入,直到过了一段时间后一直没有用户输入。一个 ISAPI DLL ,可以在被用户请求激活后长驻内存,等待用户的另一个请求,还可以在一个 DLL 里设置多个用户请求处理函数,此外, ISAPI DLL 应用程序和 WWW 服务器处于同一个进程中,效率要显著高于 CGI

每个使用 DLL 的请求都会赋给同一个处理器空间的线程, IIS 通常只是在初始化的时候为线程分好一个 线程池 后,在运转周期里就一直使用这些线程。 线程池技术 减小了创建线程开销。

ISAPI 出现在 CGI 之后,是一种优于 CGI 的动态网页开发技术, ASP 是一个更好的 ISAPI ,而 ASP.NET 是更好的 ASP

ISAPI Classes

ISAPI describes an interface for Internet servers. An example of an ISAPI server is Windows NT Server running Microsoft Internet Information Server (IIS).

HTTP filters handle server requests. They can be used to handle the following types of applications:

1 Custom authentication schemes

2 Data compression

3 Encryption

4 Logging

Filter Classes

CHttpFilter

Filters selected HTTP requests sent to an ISAPI server.

CHttpFilterContext

Manages the context for an HTTP filter. This is a helper class to handle multiple, concurrent requests of a CHttpFilter object.

Server Classes

ISAPI server extensions process server requests. MFC ISAPI classes will not process requests from a Common Gateway Interface (CGI).

CHttpServer

Extends the functionality of an ISAPI server by processing client requests.

CHttpServerContext

Manages the context for an ISAPI server extension. This is a helper class to handle multiple, concurrent requests of a CHttpServer object.

Related Classes

CHtmlStream (流 IO 、动态内存管理)

Handles caching HTML output. Functionally similar to CMemFile .

源码参考: <AFXISAPI.H> <AFXISAPI.INL> <ISAPIMIX.CPP> <ISAPI.CPP>

// AFXISAPI.H

#include <VC98//Include// HTTPEXT.H >

#include <VC98//Include// HTTPFILT.H >

/////////////////////////////////////////////////////////////////

// AFXIASPI - MFC Internet Server API support

// CHtmlStream -- manages in-memory HTML

// Status codes for HTTP transactions

// Parse Map macros

参考:

MFC 深入浅出》李久进

第十四章《 SOCKET 类的设计和实现》

Visual C++ 6.0 网络编程技术》 雷斌等

Visual C++ 6 From The Ground Up John Paul Mueller

第三部分《 Visual C++ Internet

ISAPI 实用技术指南》 K.Clements

《用 C++ 开发 Web 商用程序》

几种网络编程方式的比较

网络编程学习小结

IIS ISAPI 接口简介

C 语言写的 ISAPI 上传文件

VC网络通信API概览


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论