标题：WSAAccept()
函数简述
简述：
有条件地接受一个连接基于状态函数的返回值,选择创建或加入一个套接字组,提供QOS flowspecs,允许连接数据的转移。
函数原型　SOCKET WSAAPI WSAAccept ( 　 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等于零,那么任何关于远程地址返回接受套接字。否则,这两个参数将被填满,不管条件函数指定或返回内容。
A prototype of the condition function is as follows:
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().