您的位置:首页 > 其它

WSAAccept()函数使用解析

2015-06-17 10:14 281 查看

首先了解accept、AcceptEx、WSAAccept的区别 .

1. accept、WSAAccept是同步操作,AcceptEx是异步操作

2. WSAAccept函数早accept函数基础上添加了条件函数判断是否接受客户端连接

3. AcceptEx是异步的,可以同时发出多个AcceptEx请求,支持重叠IO操作.

WSAAccept()函数:

简述: 有条件地接受一个连接基于状态函数的返回值,选择创建或加入一个套接字组,提供QOS flowspecs,允许连接数据的转移。

函数原型:

SOCKET WSAAPI WSAAccept ( SOCKET s, struct sockaddr FAR * addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData );

参数说明:

s:标识一个套接口的描述字,该套接口在listen()后监听连接。

addr:(可选)指针,指向存放通讯层所知的连接实体地址的缓冲区。addr参数的具体格式由套接口创建时产生的地址族决定。

addrlen:(可选)指针,指向存放addr地址长度的整形数。

lpfnCondition:(可选的)用户提供的条件函数的进程实例地址。该函数根据参数传入的调用者信息作出接受或拒绝的决定,并通过给结果参数赋予特定的值来(可选地)创建和/或加入一个套接口组。

dwCallbackData:作为条件函数参数返回给应用程序的回调数据。WinSock不分析该参数。 返回值: 若无错误发生,WSAAccept()函数返回所接受套接口的描述字。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。 addrlen参数引用的整形数初始时包含了addr参数所指向的空间数,在调用返回时包含了返回地址的实际长度。



附录

这个WSAAccept函数提取第一个连接在队列中等待将要连接的socket,并检查它的条件函数,提供了指定条件函数(即非NULL)。如果条件函数返回CF_ACCEPT,WSAAccept创建一个新的套接字和执行任何套接字分组所显示的结果参数g在条件函数中。新创建的套接字具有socket相同的属性包括异步事件注册WSAAsyncSelect或WSAEventSelect,但不包括监听套接字的组ID。如果条件函数返回CF_REJECT,WSAAccept拒绝连接请求。条件函数运行在相同的线程作为该函数的功能,应尽快返回。条件函数应该返回 CF_DEFER表明没有作出决定,没有行动关于这个服务提供者连接请求。当应用程序准备采取行动在连接请求时,它将并返回再次调用WSAAccept CF_ACCEPT 或者 CF_REJECT作为条件函数的返回值。 一个套接字在默认模式(阻塞)会阻塞,直到连接存在,当一个应用程序调用WSAAccept和没有连接上pendng队列 一个套接字的非阻塞模式(阻塞)失败与错误WSAEWOULDBLOCK当一个应用程序调用WSAAccept和没有连接上pendng队列。WSAAccept后成功,并返回一个新的套接字处理,接受插座不能用于接受任何更多的连接。原始套接字保持开放和监听新的连接请求。 参数是一个结果的addr的参数填写的地址连接实体,作为已知的通信层。的确切格式addr参数是由家庭地址的通信发生。这个addrlen是一个值的结果参数;它应该最初包含空格的数量由addr指出。在返回时,它将包含实际的长度(字节)的地址返回。这个调用是使用面向连接的套接字类型如袜子流。如果addr和/或addrlen等于零,那么任何关于远程地址返回接受套接字。否则,这两个参数将被填满,不管条件函数指定或返回内容。

一个条件函数的原型如下:

int CALLBACK ConditionFunc( IN LPWSABUF lpCallerId, IN LPWSABUF lpCallerData, IN OUT LPQOS lpSQOS, IN OUT LPQOSlpGQOS, IN LPWSABUF lpCalleeId, OUT LPWSABUF lpCalleeData, OUT GROUP FAR * g, IN DWORD dwCallbackData);



ConditionFunc是应用程序提供的回调函数的占位符。函数必须位于一个DLL或应用程序模块的实际情况。它是在模块定义文件中导出。

UseMakeProcInstance一个过程实例的回调函数的地址。  

lpCallerId参数是一个值,该值的参数,该参数包含连接实体的地址。的lpCallerData是一个数值参数,包含任何用户数据。这些参数中的信息一起被发送的连接请求。如果无来电显示识别主叫方数据是可用的,相应的参数为NULL。许多网络协议不支持连接时的主叫方数据。大多数传统的网络协议可以预计到支持主叫方ID信息,在连接请求的时间。 lpCallerId点的buf所指向的WSABUF部分一个SOCKADDR。根据它的地址族(通常由铸造的的SOCKADDR一些类型特定的地址族)的的SOCKADDR的解释。  

lpSQOS参数的引用FLOWSPEC的结构为插座指定的来电,为每个方向之一,任何额外的供应商特定的参数。适用于任何单向插座的发送或接收流规范值将被忽略。一个NULL值表明,有没有调用者提供QOS和,没有谈判是可能的。一个非NULL lpSQOS的指针指示的QoS协商是发生或供应商没有谈判,准备接受QOS要求。  lpGQOS参数(保留以供将来使用插座组)引用的FLOWSPEC的结构套接字组的调用者创建,为每个方向之一,任何额外的供应商特定的参数。 lpGQOS一个NULL值表示无来电显示提供的服务质量。如果协商是发生的服务质量信息可以被返回。  

lpCalleeId是一个值参数,包含本地地址,所连接的实体。 lpCalleeId点的buf所指向的WSABUF部分一个SOCKADDR。根据它的地址族(通常由铸造的的SOCKADDR一些类型特定的地址族)的的SOCKADDR被解释。  

lpCalleeData是一个结果参数,用于为所使用的条件的函数来提供用户数据返回到连接的实体。最初的lpCalleeData-> len个包含由服务提供商分配的缓冲区,并指出,通过lpCalleeData - >缓冲区的长度。通过用户数据返回给调用者的值为零,则表示不支持。条件函数复制到lpCalleeData-> len个字节的数据到lpCalleeData - >缓冲区,然后更新lpCalleeData-> len个显示实际传输的字节数。如果没有用户数据将被传递回给调用者,条件函数应设置lpCalleeData的 - > len个零。所有的地址和用户数据的格式的特定套接字所属的地址族。  保留供未来使用插座组:分配的结果参数g在条件函数来表示以下操作:  1、若果&g是一个现有的插座组ID,加s到该组,本组所设定的所有要求得到满足;2、如果&g = SG_UNCONSTRAINED_GROUP的,创建一个无约束的插座组,有S的第一个成员;3、如果&g = SG_CONSTRAINED_GROUP的,创建一个受限的插座组,有S的第一个成员;4、如果&g =零,没有组进行操作。  对于无约束的群体,任何一组插槽可以组合在一起,只要他们支持由一个单一的服务提供商。可以由一个有限的插座组仅面向连接的套接字,并要求所有组合插座上的连接到相同的地址在同一主机上。对于新创建的套接字组,新的组ID可以检索利用getsockopt选项SO_GROUP_ID,如果此操作成功完成。一个插座组及其相关联的ID仍然有效,直到最后一个套接字被关闭属于该插座组。插座组ID是唯一的,对于一个给定的服务供应商的所有进程。  dwCallbackData参数值传递的条件功能的dwCallbackData在原来的WSAAccept调用的参数传递的值。这个值被解释只能由Windows套接字第2版客户端。这允许客户端通过一些WSAAccept调用网站的条件函数的上下文信息。这也提供了与任何所需的附加信息,以确定是否接受的连接或没有的功能的条件。一个典型的用法是通过适当投指针的数据结构,它包含与此套接字关联的应用程序定义的对象的引用。

错误代码

WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。 WSAECONNREFUSED 根据条件函数的返回值(CF_REJECT)强制拒绝连接请求。 WSAENETDOWN 网络子系统失效。

WSAEFAULT addrlen参数太小(小于sockaddr结构的大小),或者lpfnCondition并不是用户空间的一部分。

WSAEINTR 通过WSACancelBlockingCall()函数取消(阻塞)调用。

WSAEINPROGRESS 一个阻塞WinSock调用正在进行。

WSAEINVAL WSAAccept()调用前未执行listen()调用;条件函数中的g参数非法;条件函数的返回值非法;套接口处于非法状态。

WSAEMFILE WSAAccept()调用时排队队列非空,且无可用套接口描述字。 WSAENOBUFS 无可用缓冲区空间。

WSAENOTSOCK 描述字不是一个套接口。

WSAEOPNOTSUPP 所引用的套接口不是支持面向连接服务类型的。 WSATRY_AGAIN 根据条件函数的返回值(CF_DEFER) ,连接请求被推迟。

WSAEWOULDBLOCK 套接口标志为非阻塞,无连接请求供接受。

WSAEACCES 被推迟的连接请求超时或撤销。 另请参阅:accept(), bind(), connect(), getsockopt(),listen(), select(), socket(), SAAsyncSelect(), WSAConnect().
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: