📄 16.5.1 相关函数说明.txt
字号:
16.5.1 相关函数说明
1. WSAAsyncSelect函数
int WSAAsyncSelect(SOCKET s , HWND hWnd , unsigned int wMsg , long lEvent)
该函数为指定的套接字请求基于Windows消息的网络事件通知,井自动将该套接字设置为非阻塞模
式。该函数有三个参数,其含义分别如下所述:
. s
标识请求网络事件通知的套接字描述符。
. hWnd
标识一个网络事件发生时接收消息的窗口的句柄。
. wMsg
指定网络事件发生时窗口将接收到的消息。
. lEvent
指定应用程序感兴趣的网络事件,该参数可以是表 16.1中列出的值之一,井且可以采用位或操作来
构造多个事件。
表 16.1 IEvent参数的取值
取值 说明
FD_READ 应用程序想要接收有关是否可读的通知,以便读取数据
FD_WRITE 应用程序想要接收有关是否可写的通知,以便发送数据
FD_OOB 应用程序想要接收是否带外(OOB )数据抵达的通知
FD_ACCEPT 应用程序想要接收与进入连接有关的通知
FD_CONNECT 应用程序想要接收连接操作已完成的通知
FD_CLOSE 应用程序想要接收与套接字关闭有关的通知
FD_QOS 应用程序想要接收套接字"服务质量"发生更改的通知
FD_GROUP_Qos 应用程序想要接收套接字组"服务质量"发生更改的通知
FD_ROUT卫吁 Gll叮TERFACE CHANGE 应用程序想要接收在指定的方向上,与路由接口发生变化有关
的通知
FD_ADDRESS_LIST_CHANGE 应用程序想要接收针对套接字的协议家族,本地地址列表发生变化的通
知
2. WSAEnumProtocols
int WSAEnumProtocols ( LPINT lpiProtocols , LPWSAPROTOCOL_INFO lpProtocolBuffer, 工
LPDWORD lpdwBufferLength )
Win32平台支持多种不同的网络协议,采用 Winsock2就可以编写可直接使用任何一种协议的网络应
用程序了。通过 WSAEnumProtocols函数可以获得系统中安装的网络协议的相关信息。该函数各个参
数的含义如下所述:
. lpiProtocols
一个以 NULL结尾的协议标识号数组。这个参数是可边的,如果 lpiProtocols为 NULL.则
WSAEnumProtocols函数将返回所有可用协议的信息,否则,只返回数组中列出的协议信息。
. IpProtocolBuffer
out类型的参数,作为返回值使用,一个用 WSAPROTOCOL INFO结构体填充的缓冲区。 WSAPROTOCOL_
剧FO结构体用来存放或得到一个指定协议的完整信息。
. lpdwBufferLength
inlout类型的参数。在输入时,指定传递给 WSAEnumProtocols函数的 lpProtocolBuffer缓冲区的
长度:在输出时,存有获取所有请求信息需传递给 WSAEnumProtocols函数的最
小缓冲区长度。 WSAEnumProtocols函数不能重复调用,传入的缓冲区必须足够大以便能存放所有的
元素。这个规定降低了该函数的复杂度,并且由于一个机器上装载的协议数目往往很少,
因此并不会产生问题。
3. WSAStartup
WSAStartup函数将初始化进程使用的 WS2_32.DLL.该函数原型声明如下所示:
int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData) ;
.
WSAStartup函数有两个参数,其含义分别如下所述 :
wVersionRequested
解
凯
:
一九…
忡
调用进程可以使用的 Windows Sockets支持的最高版本。该参数的高位字节指定 Winsock库的副版
本,而低位字节则是主版本。
. lpWSAData
out类型的参数,作为返回值使用,是一个指向 WSADATA数据结构类型变量的指针,用来接收 Windows
Sockets实现的细节。
4. WSACleanup
WSACleanup函数将终止程序对套接字库 ( WS2 32.DLL)的使用。该函数的原型声明如下所示。
int WSACleanup (void);
5. WSASocket
Winsock库中的扩展函数 WSASocket将创建套接宇,其原型声明如下所示:
SOCKET WSASocket ( int af , int type , int protocol , LPWSAPROTOCOL_INFO lpProtocollnfo,
GROUP g , DWORD dwFlags );
该函数前三个参数和前面介绍过的 socket函数的前三个参数含义相同,其他参数的含义如下所述:
'
. lpProtocolInfo
一个指向 WSAPROTOCOL-mFO结构体的指针,该结构定义了所创建的套接字的特性。如果 lpProtoco
lInfo为 NULL,则 WinSock2 DLL使用前三个参数来决定使用哪一个服务提供者,它选择能够支持规
定的地址族、套接字类型和协议值的第一个传输提供者。如果 lpProtoco lInfo不为 NULL,则套接
字绑定到与指定的结构 WSAPROTOCOL_INFO相关的提供者。
. g
保留。
. dwFlags
指定套接字属性的描述。如果该参数的取值为 WSA_FLAG_OVERLAPPED,那么将创建一个重叠套接字,
这种类型的套接字后续的重叠操作与前面讲述的文件的重叠操作是类似的。随后在套接字上调用
WSASend, WSARecv,WSASendTo, WSARecvFrom, WSAloctl 这些函数都会立即返回。在这些操作完成
之后,操作系统会通过某种方式来通知调用线程,后者就可以根据通知信息判断操作是否完成。
6. WSARecvFrom int WSARecvFrom ( SOCKET s , LPWSABUF lpBuffers , DWORD dwBufferCount ,
LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags , struct sockaddr FAR *lpFrom, LP工 NT
lpFromlen , LPWSAOVERLAPPED lpoverlapped, LPWSAOVERLAPPED_COMPLETION_ROUT工 NE
lpCompletionRoutine );
...... 1609
第 16章线程同步
WSARecvFrom函数接收数据报类型的数据,井保存数据发送方的地址。该函数有 9个参数,其含义分
别如下所述:
. s
标识套接宇描述符。
. lpBuffers
in/out类型的参数,一个指向 WSABUF结构体数组的指针,该结构体的定义如下所示。
typedef struct一_WSABUF {
u_long len; // buffer length
char FAR *buf; // pointer to buffer
} WSABUF , FAR * LPWSABUF;
每一个 WSABUF结构体包含一个指向缓冲区的指针 Cbuf成员〉和该缓冲区的长度
Clen )。
. dwBufferCount
lpBu仔ers数组中 WSABUF结构体的数目。
. IpNumberOfBytesRecvd
out类型的参数,如果接收操作立即完成,那么该参数是一个指向本次调用所接收的字节数的指针。
. IpFlags
in/out类型的参数,一个指向标志位的指针,这些标志将会影响函数的行为。该参数的取值如表 16.2
所示,可以利用位或操作将这些标志组合起来使用。
表 16.2 IpFlags参数取值
标,才臼= 说明
MSG PEEK 浏览到来的数据。这些数据被复制到缓冲区,但并不从输入队列中移除。此标志仅对非
重叠套接字 有效
MSG OOB 处理带外(OOB )数据
MSG_PARTlAL 此标志仅用于面向消息的套接字。作为输出参数时,此标志表明数据是发送方传送的
消息的一部分。消息的剩余部分将在随后的接收操作中被传送。如果随后的某个接收操作没有此标
志,就表明这是发 送方发送的消息的尾部。作为输入参数时,此标志表明接收操作应该是完成的,
即使只是→条消息的部分数据已被服务提供者所接收。
. IpFrom
out类型的参数,是一个可选的指针,指向重叠操作完成后存放源地址的缓冲区。
. IpFrollùen
i n/out类型的参数,一个指向 lpFrom指定的缓冲区大小的指针,仅当指定了 IpFrom参数时才需要
使用这个参数。
. lpOverlapped
一个指向 WSAOVERLAPPED结构体的指针 (对于非重叠套接字则忽略)。
. IpCompletionRoutine
一个指向接收操作完成时调用的完成例程的指针(对于非重叠套接宇则忽略)。
610 I ~~~
VCII深λ详解
如果创建的是重叠套接字,在使用WSARecvFrom函数时,一定要注意最后两个参数的值。因为这时将
采用重叠10操作, WSARecvFrom函数会立即返回。当接收数据这一操作完成之后,操作系统会调用
lpCompletionRoutine参数指定的例程来通知调用线程,这个例程实际上就是一个回调函数,该函数
的原型声明如下所示:
void CALLBACK CompletionROUT工NE(
IN DWORD dwError ,
工N DWORD cbTransferred,
工N LPWSAOVERLAPPED lpOverlapped,
工N DWORD dwFlags
通过WSARecvFrom函数的第2个参数,可以知道,在调用该函数接收数据时,可以同时指定多个WASBUF
结构体变量,一起来接收数据,并通过该函数的第3个参数指定 WASBUF结构体的数量。
为什么要定义多个 WASBUF结构体变量同时去接收数据呢?是数据量太大?当然不是,如果是数据量太
大,可以定义一个大容量的数据缓冲区进行一次接收操作就可以了,并没有必要定义多个缓冲区。
那么同时指定多个缓冲区有什么好处呢?假如我们要开发一个防火墙产品,其中包括防火墙管理中
心,既然作为管理中心,就需要接收防火墙日志信息,而日志信息的格式通常都是由我们自己定义
的,也就是在一连串的字节流中,人为地
定义前几个字节、中间几个字节,以及最后几个字节各自表示的含义,如果采用WSARecv t From函
数接收数据,就可以针对传送的信息,分别提供不同的缓冲区去接收,然后相应地取出缓冲区中的
数据进行处理,这样就避免通过编码去切分字节流。这就是提供多个缓冲区同时接收数据的好处。
7. WSASendTo
int WSASendTo( SOCKET s , LPWSABUF lpBuffers ,-DWORD dwBufferCount , LPDWORD
lpNumberOfBytesSent , DWORD dwFlags , const struct sockaddr FAR *lpTo, int iToLen,
LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUT工NE lpCompletìonRoutine };
. s
标识一个套接字 (可能己连接)的描述符。
. lpBuffers
一个指向WSABUF结构体的指针。每一个WSABUF结构体包含一个缓冲区的指针和缓冲区的长度。
. dwBufferCount
lpBuffers数组中WSABUF结构体的数目。
. IpNumberOtBytesSent
out类型的参数,如果发送操作立即完成,则为一个指向本次调用所发送的字节数的指针。
而稳"‘ I 611
、
第 16
. dwFlags
指示影响操作行为的标志位。本例设置为 O即可。
.1pTo
可选指针,指向目标套接字的地址。
. iToLen
lpTo中地址的长度。
. lpOverlapped
一个指向 WSAOVERLAPPED结构的指针(对于非重叠套接字则忽略〉。
. lpCompletionRoutine
一个指向接收操作完成时调用的完成例程的指针(对于非重叠套接字则忽略)。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -