![](https://csdnimg.cn/release/download_crawler_static/85937922/bg5.jpg)
4. 创建套接字
5. 调用 WSAAsyncSelect()
6. 编写 WindowProc()
MFC 中的应用方法
• WSAAsynSelect 在 MFC 中使用流程
• (1)、使用#define 语句定义套接字网络事件设置用户消息值,一般为 WM_USER+N 形式。#define WM_USER_SERVER WM_USER+1
• (2)、调用 WSAAsynsSelect 函数,为套接字设定"网络事件-用户消息-消息接收窗体"的对应关系。
• (3)、在消息接收窗体的代码的消息映射模块中,加入 ON_MESSAGE 宏,设定用户消息的处理函数。
• ON_MESSAGE(WM_USER_SERVER, OnServerMsg)
• (4)、编写用户处理函数,该函数应该首先使用 WSAGETSELECTERROR 宏判断是否有错误发生:
• 然后根据 wParam 值了解是哪一个套接口上发生了网络事件从而引起用户消息被发送:最后使用
• WSAGETSELECTEVENT 宏来了解所发生的网络事件,从而进行相应处理。
WSAEventSelect 模型
• WSAEventSelect 模型是 WinSock 提供的另一个异步 I/O 模型,与 WSAAsyncSelect 模型类似,也允许应用程序在一个或多个套接字上
接收以事件为基础的网络事件通知,并且支持的网络事件与 WSAAsyncSelect 模型一样。
• 与 WSAAsyncSelect 模型的主要区别在于网络事件会被发送到一个事件对象句柄,而不是发送到一个窗口。
WSAEventSelect 优缺点
• 优点:简单、不需要窗口环境。
• 缺点:事件对象数目受限制,最多 64。由于一个套接字对应一个事件对象,故支持的套接字数量也为 64。
基于 WSAEventSelect 模型的多线程服务器
问题:单线程的 WSAEventSelect 服务器容纳的事件对象受限,亦即可以管理的最大套接字数量为 64。
思路:采用多线程,当有新的连接请求到来时,如果一个线程可容纳的连接达到上限(64),创建新的线程处理连接。
程序构成:主线程负责监听,创建连接套接字,将套接字分配给连接数未达到上限的线程。
为此先介绍两个重要的结构:
➢ SOCKET_OBJ
➢ THREAD_OBJ
重叠模型的基本原理
• 重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个 Winsock I/O 操作,在这些提交的 I/O 操作完成之
后,应用程序可以接收到完成通知,从而进行相应的处理。
• 两种方法可以接收到重叠 IO 操作的完成的通知:
1. 在事件对象上等待通知(event object notification)
2. 完成例程(completion routines) ,注意:并不是完成端口
关于缓冲区和重叠操作
• 对接收方,应用程序使用 WSARecv 函数或 WSARecvFrom 函数来提供存放接收数据的缓冲区。
• 如果数据在网络接收以前,应用程序已经提供了一个或多个缓冲区,那么接收的数据就可以立即存放进用户缓冲区。
• 如果在应用程序提供数据缓冲区时已经有数据到来,那么接收的数据将被立即拷贝进用户缓冲区。
• 如果数据到来时,应用程序没有提供接收缓冲区,那么网络将回到同步操作方式,传送过来的数据将被存放进内部缓冲区,直到应用
程序发出了接收调用并且提供了接收缓冲区,这时接收的数据才被拷贝进接收缓冲区。
• 特例:当应用程序使用 setsockopt 函数把内部接收缓冲区长度设置为 0 时,对可靠传输协议,数据直到应用程序提供了接收缓冲区后
才被接收,而对不可靠传输协议,数据将会丢失。
• 对发送方,应用程序使用 WSASend 函数或 WSASendTo 函数提供一个指向已填充的数据缓冲区的指针。
• 应用程序不应在网络使用完该缓冲区的数据以前以任何方式破坏该缓冲区的数据。
• 重叠发送和 接 收 调用会立即 返 回 。如返回值 是 0 , 那么表明 I/O 操作已经 完 成,对应的完 成 指 示也可得到 。 如 果返回值是
SOCKET_ERROR,并且错误代码是 WSA_IO_PENDING,那么表明重叠操作已经被成功初始化,今后发送缓冲区被用完或者接收缓