Windows Sockets 规范及应用
发布: 2008-4-30 22:53 | 作者: 施炜 李铮 秦颍 | 来源: 网络转载 | 查看: 401次
6.12 分散/聚集方式I/O
WSASend(),WSASendTo(),WSARecv()和WSARecvFrom()函数都以应用程序缓冲区数组作为输入参数,因此它们可以进行分散/聚集方式(向量方式)的I/O操作。如果应用程序需要传送的信息除了信息体外还包含了一个或多个固定长度的头时,这种操作是很有用的。这些头在发送之前不需要由应用程序连接到一个连续的缓冲区中。同样的,在接收时,这些头会自动的分离到各自的缓冲区中。
如果接收时应用程序提供了多个缓冲区,当有数据到来时,操作就结束了,不论提供的缓冲区是否都被使用了。
6.13 协议无关的多点通讯
Windows Sockets 2支持基本的数据传输以一般的方式使用不同的传输协议。Windows Sockets 2也支持应用程序以一般的方式使用传输协议的多点通讯能力。
目前的多点通讯实现在节点加入一个多点对话的方式上有很大的不同。例如,是否有一个特殊的节点被指定为中心节点或者就是根节点;数据是在所有节点之间交换还是只在根节点和它的叶节点之间交换。Windows Sockets 2中的PROTOCOL_INFO结构允许一个协议声明它的多点通讯的各种特性。通过检查这些特性,应用程序可以知道在使用Windows Sockets 2函数设置,使用和拆除多点对话时应该遵循那一种协定。
Windows Sockets 2中为支持多点通讯而作的增加如下:
* PROTOCOL_INFO结构中的两个特性位。
* 为WSASocket()的参数iflags定义的四个标志。
* 一个新函数-WSAJoinLeaf(),它用来在多点对话中加入一个叶节点。
* 两个WSAIoctl()的命令代码。
6.14 新增套接口选项一览
Windows Sockets 2新增的套接口选项归纳如下:
选项值 类型 含义 缺省值
SO_GROUP_ID GROUP 套接口所属的套接口组 NULL
SO_GROUP_PRIORITY int 套接口在套接口组中的 0
相对优先级
SO_MAX_MSG_SIZE int 对于基于消息的套接口, 决定于
这一选项指明了一个消 实现
息的最大长度。对于基
于流的套接口,这一选
项没有任何意义。
SO_PROTOCOL_INFO struct 描述捆绑到套接口的协 决定于
PROTOCOL 议的信息。 协议
_INFO
PVD_CONFIG char 一个包含了服务提供者 决定于
FAR * 配置信息的不透明的数 实现
据结构对象。
6.15 新增套接口ioctl操作代码
Windows Sockets 2新增的ioctl操作代码归纳如下。WSAIoctol()函数支持所有为ioctlsocket()函数定义的操作代码。
操作代码 输入类型 输出类型 含义
SIO_ASSOCIATE_HANDLE 决定于伴随 没有使用。 把套接口与一个指定
的API。 的伴随接口连接。
SIO_ENABLE_CIRCULAR_ 没有使用 没有使用 允许循环队列。
QUEUEING
SIO_FIND_ROUTE struct 没有使用 请求找到对应于指定
sockaddr 地址的例程。
SIO_FLUSH 没有使用 没有使用 废除当前发送队列的内容。
SIO_GET_BROADCAST_ 没有使用 没有使用 得到特定协议的广播地址,
该地址可以使用在send()
函数和WSASend()函数中。
SIO_GET_QOS 没有使用 QOS 得到套接口当前的流协议。
SIO_GET_GROUP_QOS 没有使用 QOS 得到套接口所属套接口组的
流协议。
SIO_MULTIPOINT_LOOK BOOL 没有使用 决定多点对话的数据是否由
本地主机的同一套接口接收。
SIO_MULTICAST_SCOPE int 没有使用 定义允许多方传送的空间。
SIO_SET_QOS QOS 没有使用 为套接口建立新的流协议。
SIO_SET_GROUP_QOS QOS 没有使用 为套接口所属套接口组建立
新的流协议。
SIO_TRANSLATE_HANDLE int 决定于伴 得到一个上下文有效的套接口
随API 对应的句柄。
6.16 新增函数一览
Windows Sockets 2新增的函数列在下表中:
WSAAccept() accept()函数的扩展版本,它支持条件接收和套接口分组。
WSACloseEvent() 释放一个事件对象。
WSAConnect() connect()函数的扩展版本,它支持连接数据交换和QOS规范。
WSACreateEvent() 创建一个事件对象。
WSADuplicateSocket() 为一个共享套接口创建一个新的套接口描述字。
WSAEnumNetworkEvents() 检查是否有网络事件发生。
WSAEnumProtocols() 得到每个可以使用的协议的信息。
WSAEventSelect() 把网络事件和一个事件对象连接。
WSAGetOverlappedResu() 得到重叠操作的完成状态。
WSAGetQOSByName() 对于一个传输协议服务名字提供相应的QOS参数。
WSAHtonl() htonl()函数的扩展版本。
WSAHtons() htons()函数的扩展版本。
WSAIoctl() ioctlsocket()函数的允许重叠操作的版本。
WSAJoinLeaf() 在多点对话中加入一个叶节点。
WSANtohl() ntohl()函数的扩展版本。
WSANtohs() ntohs()函数的扩展版本。
WSARecv() recv()函数的扩展版本。它支持分散/聚集I/O和重叠套接口操作。
WSARecvDisconnect() 终止套接口的接收操作。如果套接口是基于连接的,得到拆除数据。
WSARecvFrom() recvfrom()函数的扩展版本。它支持分散/聚集I/O和重叠套接口操作。
WSAResetEvent() 重新初始化一个数据对象。
WSASend() send()函数的或者版本。它支持分散/聚集I/O和重叠套接口操作。
WSASendDisconnect() 启动一系列拆除套接口连接的操作,并且可以选择发送拆除数据。
WSASendTo() sendto()函数的扩展版本。它支持分散/聚集I/O和重叠套接口操作。
WSASetEvent() 设置一个数据对象。
WSASocket() socket()函数的扩展版本。它以一个PROTOCOL_INFO结构作为输入参数,并且允许创建重叠套接口。它还允许创建套接口组。
WSAWaitForMultipleEvents() 阻塞多个事件对象。
第七章 Windows Sockets 2扩展库函数简要参考
7.1 WSAAccept()
简述:根据条件函数的返回值有条件地接受连接,同时(可选地)创建和/或加入一个套接口组。
SOCKET WSAAPI WSAAccept ( SOCKET s, struct
sockaddr FAR * addr, int FAR * addrlen,
LPCONDITIONPROC lpfnCondition, DWORD
dwCallbackData );
s:标识一个套接口的描述字,该套接口在listen()后监听连接。
addr:(可选)指针,指向存放通讯层所知的连接实体地址的缓冲区。addr参数的具体格式由套接口创建时产生的地址族决定。
addrlen:(可选)指针,指向存放addr地址长度的整形数。
lpfnCondition:(可选的)用户提供的条件函数的进程实例地址。该函数根据参数传入的调用者信息作出接受或拒绝的决定,并通过给结果参数赋予特定的值来(可选地)创建和/或加入一个套接口组。
dwCallbackData:作为条件函数参数返回给应用程序的回调数据。WinSock不分析该参数。
返回值:
若无错误发生,WSAAccept()函数返回所接受套接口的描述字。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
addrlen参数引用的整形数初始时包含了addr参数所指向的空间数,在调用返回时包含了返回地址的实际长度。
错误代码:
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().
7.2 WSACloseEvent()
简述:关闭一个开放的事件对象句柄。
#include <winsock2.h>
BOOL WSAAPI WSACloseEvent( WSAEVENT hEvent );
hEvent:标识一个开放的事件对象句柄。
返回值:
如果函数顺利完成,返回值为真TRUE。如果失败,返回值为假FALSE。可用 WSAGetLastError()调用获取更多的错误信息。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSA_INVALID_HANDLE hEvent不是一个合法的事件对象句柄。
另请参阅: WSACreateEvent(), WSAEnumNetworkEvents(),WSAEventSelect(), WSAGetOverlappedResult(),WSARecv(), WSARecvFrom(), WSAResetEvent(),WSASend(), WSASendTo(), WSASetEvent(),WSAWaitForMultipleEvents().
7.3 WSAConnect()
简述:创建一个与远端的连接,交换连接数据,并根据所提供的流描述确定所需的服务质量。
#include <winsock2.h>
int WSAAPI WSAConnect ( SOCKET s, const struct
sockaddr FAR * name,
int namelen, LPWSABUF lpCallerData, LPWSABUF
lpCalleeData,
LPQOS lpSQOS, LPQOS lpGQOS );
s:用于描述一个未连接套接口的描述字。
name:欲与套接口连接的远端名字。
namelen:名字长度。
lpCallerData:指向用户数据的指针,该数据在建立连接时将传送到远端。
lpCalleeData:指向用户数据的指针,该数据在建立连接时将从远端传送回本机。
lpSQOS:指向套接口s流描述的指针,每个方向一个。
lpGQOS:指向套接口组流描述的指针。(如果有套接口组的话)
返回值:
如果无错误发生,WSAConnect()返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
对于阻塞套接口来说,返回值表示连接试图是否成功。
对于非阻塞套接口来说,连接试图不一定马上完成。在这种情况下,WSAConnect()返回SOCKET_ERROR,且WSAGetLastError()返回WSAEWOULDBLOCK. 此时应用程序可以:
1。利用select()函数,通过检查套接口是否可写来判断连接请求是否完成。或者,
2。如果应用程序已使用WSAAsyncSelect()函数来确定对连接事件的兴趣,则当连接操作完成时应用程序将收到FD _CONNECT通知。或者,
3。如果应用程序已使用WSAEventSelect()函数来确定对连接事件的兴趣,则当连接操作完成时相应的事件对象将设置信号。
对于一个非阻塞套接口来说,在连接试图完成之前,任何对该套接口的WSAConnect()调用都将以WSAEALREADY错误失败。
如果返回值指出连接试图失败(例如WSAECONNREFUSED, WSAENETUNREACH,WSAETIMEDOUT)则应用程序可对该套接口再次调用WSAConnect()函数。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEADDRINUSE 所指地址已被使用。
WSAEINTR 通过WSACancelBlockingCall()函数中止了阻塞调用。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。(参见B.3.6.6节)
WSAEALREADY 在所指定的套接口上正在进行一个非阻塞的connect()或WSAConnect()调用。
WSAEADDRNOTAVAIL 本地机器上无法获得所指定的地址。
WSAEAFNOSUPPORT 所指定地址族中的地址无法与本套接口一起使用。
WSAECONNREFUSED 连接试图被拒绝。
WSAEFAULT name或namelen参数不是用户地址空间的一个有效部分;namelen参数太小; lpCalleeData、 lpSQOS和lpGQOS的缓冲区太小;或者lpCallerData的缓冲区太大。
WSAEINVAL 套接口已与一个地址捆绑。
WSAEINVAL 套接口未与一个地址捆绑。
WSAEINVAL s参数为监听套接口。
WSAEISCONN 套接口已经连接(仅适用于面向连接的套接口)。
WSAENETUNREACH 当前无法从本主机联系网络。
WSAENOBUFS 无可用缓冲区,套接口未连接。
WSAENOTSOCK 描述字不是一个套接口。
WSAEOPNOTSUPP lpSQOS和lpGQOS中的流描述无法满足。
WSAEPROTONOSUPPORT 服务提供者不支持lpCallerData参数。
WSAETIMEDOUT 连接试图超时,连接未建立。
WSAEWOULDBLOCK 套接口标志为非阻塞,连接无法立即完成。当套接口用select()函数设置为读时,可调用select()。
WSAEACCES 由于setsockopt()时未允许SO_BROADCAST,无法将一个数据报套接口与一个广播地址连接。
另请参阅: accept(), bind(), connect(), getsockname(),getsockopt(), socket(), select(),
WSAAsyncSelect(), WSAEventSelect().
7.4 WSACreateEvent()
简述:创建一个新的事件对象。
#include <winsock2.h>
WSAEVENT WSAAPI WSACreateEvent( VOID );
返回值:
如果函数成功,则返回值即是事件对象的句柄。
如果函数失败,返回WSA_INVALID_EVENT。应用程序可通过调用WSAGetLastError()函数获取进一步的错误信息。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSA_NOT_ENOUGH_MEMORY 无足够内存创建事件对象。
另请参阅: WSACloseEvent(), WSAEnumNetworkEvents(),WSAEventSelect(), WSAGetOverlappedResult(),WSARecv(), WSARecvFrom(), WSAResetEvent(),WSASend(), WSASendTo(), WSASetEvent(),WSAWaitForMultipleEvents().
7.5 WSADuplicateSocket()
简述:为一个共享套接口创建一个新的描述字。
#include <winsock2.h>
SOCKET WSAAPI WSADuplicateSocket ( SOCKET s,
WSATASK hTargetTask );
s:指定本地套接口描述字。
hTargetTask:指定使用共享套接口的目标任务的句柄。
返回值:
若无错误发生,WSADuplicateSocket()返回新的套接口描述字。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINVAL 参数中有非法值。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。(参见B.3.6.6节)
WSAEMFILE 无可用套接口描述字。
WSAENOBUFS 无可用缓冲区空间,套接口未创建。
WSAENOTSOCK 描述字不是一个套接口。
另请参阅:
7.6 WSAEnumNetworkEvents()
简述:检测所指定套接口上网络事件的发生。
#include <winsock2.h>
int WSAAPI WSAEnumNetworkEvents ( SOCKET s,
WSAEVENT hEventObject, LPWSANETWORKEVENTS
lpNetworkEvents, LPINT lpiCount);
s:标识套接口的描述字。
hEventObject:(可选)句柄,用于标识需要复位的相应事件对象。
lpNetworkEvents:一个WSANETWORKEVENTS结构的数组,每一个元素记录了一个网络事件和相应的错误代码。
lpiCount:数组中的元素数目。在返回时,本参数表示数组中的实际元素数目;如果返回值是WSAENOBUFS,则表示为获取所有网络事件所需的元素数目。
返回值:
如果操作成功则返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINVAL 参数中有非法值。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。(参见B.3.6.6节)
WSAENOBUFS 所提供的缓冲区太小。
另请参阅: WSAEventSelect()
7.7 WSAEnumProtocols()
简述:获取现有传送协议的相关信息。
#include <winsock2.h>
int WSAAPI WSAEnumProtocols ( LPDWORD
lpdwProtocols, LPVOID lpProtocolBuffer, LPDWORD
lpdwBufferLength);
lpdwProtocols:一个以NULL结尾的协议标识号数组。本参数可选;如果lpdwProtocols为 NULL,则返回所有可用协议的信息,否则的话只返回数组中所开列的协议信息。
lpProtocolBuffer:一个用PROTOCOL_INFO结构填充的缓冲区。参见下文中对PROTOCOL_INFO结构的具体描述。
lpdwBufferLength:输入时,存有传递给WSAEnumProtocols()函数的lpProtocolBuffer缓冲区长度。输出时,表示为获取所有信息需传递给WSAEnumProtocols()函数的缓冲区长度。本函数不能重复调用;传入的缓冲区必须足够大以能存放所有的元素。这个规定降低了该函数的复杂度。由于一个机器上装载的协议数目往往是很小的,所以并不会产生问题。
返回值:
若无错误发生,WSAEnumProtocols()返回协议的数目。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINPROGRESS 一个阻塞WinSock调用正在进行。
WSAEINVAL 参数中有非法值。
WSAENOBUFS 缓冲区太小,无法保存所有PROTOCOL_INFO结构及其相关信息。传入的缓冲区大小至少应等于lpdwBufferLength中返回的值。
7.8 WSAEventSelect()
简述:确定与所提供的FD_XXX网络事件集合相关的一个事件对象。
#include <winsock2.h>
int WSAAPI WSAEventSelect ( SOCKET s, WSAEVENT
hEventObject, long lNetworkEvents );
s:一个标识套接口的描述字。
hEventObject:一个句柄,用于标识与所提供的FD_XXX网络事件集合相关的一个事件对象。
lNetworkEvents:一个屏蔽位,用于指定感兴趣的FD_XXX网络事件组合。
返回值:
如果应用程序指定的网络事件及其相应的事件对象成功设置,则返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
在使用select()和WSAAsyncSelect()函数时,WSAEventSelect()常用来决定何时进行数据传送操作(如send()或recv()),并期望能立即成功。但是一个稳定的应用程序应该做好这样的准备,即事件对象被设置,并且一个WinSock调用以WSAEWOULDBLOCK立即返回 。举例来说,有可能发生下述操作序列:
(i) 套接口s上到达数据;WinSock设置了WSAEventSelect事件对象。
(ii) 应用程序进行其他操作。
(iii) 在进行操作时,应用程序调用了ioctlsocket(s, FIONREAD...)并发现有数据可读。
(iv) 应用程序调用一个recv(s,...)来读取数据。
(v) 最后应用程序等待WSAEventSelect()所指定的数据对象,该数据对象指出数据可读。
(vi) 应用程序调用recv(s,...),但以WSAEWOULDBLOCK错误失败。
其他的操作序列也是可能的。
成功地记录了网络事件的发生(通过设置内部网络事件记录的相应位),并且将相应的事件对象设置了信号后,不会对该网络事件作进一步的操作,直到应用程序调用了相应的函数显式地重新允许该网络事件及相应事件对象的信号。
网络事件 重新允许函数
FD_READ recv() 或 recvfrom()
FD_WRITE send() 或 sendto()
FD_OOB recv()
FD_ACCEPT accept() 或WSAAccept(),直到返回的错误代码为 WSATRY_AGAIN,指明条件函数返回CF_DEFER。
FD_CONNECT NONE
FD_CLOSE NONE
FD_QOS 用SIO_GET_QOS 命令调用WSAIoctl()。
FD_GROUP_QOS 用SIO_GET_GROUP_QOS命令调用WSAIoctl()。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINVAL 参数中有非法值,或者指定的套接口处于非法状态。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。(参见B.3.6.6节)
WSAENOTSOCK 描述字不是一个套接口。
另请参阅:WSACloseEvent() ,WSACreateEvent(),WSAEnumNetworkEvents(),WSAGetOverlappedResult(),WSAWaitForMultipleEvents().
7.9 WSAGetOverlappedResult()
简述:返回指定套接口上一个重叠操作的结果。
#include <winsock2.h>
BOOL WSAAPI WSAGetOverlappedResult( SOCKET s,
LPWSAOVERLAPPED lpOverlapped, LPDWORD
lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags );
s:标识套接口。这就是调用重叠操作(WSARecv()、 WSARecvFrom()、WSASend()、WSASendTo() 或 WSAIoctl())时指定的那个套接口。
lpOverlapped:指向调用重叠操作时指定的WSAOVERLAPPED结构。
lpcbTransfer:指向一个32位变量,该变量用于存放一个发送或接收操作实际传送的字节数,或WSAIoctl()传送的字节数。
fWait:指定函数是否等待挂起的重叠操作结束。若为真TRUE则函数在操作完成后才返回。若为假FALSE且函数挂起,则函数返回FALSE,WSAGetLastError()函数返回 WSA_IO_INCOMPLETE。
lpdwFlags:指向一个32位变量,该变量存放完成状态的附加标志位。如果重叠操作为 WSARecv()或WSARecvFrom(),则本参数包含lpFlags参数所需的结果。
返回值:
如果函数成功,则返回值为真TRUE。它意味着重叠操作已经完成,lpcbTransfer所指向的值已经被刷新。应用程序可调用WSAGetLastError()来获取重叠操作的错误信息。
如果函数失败,则返回值为假FALSE。它意味着要么重叠操作未完成,要么由于一个或多个参数的错误导致无法决定完成状态。失败时,lpcbTransfer指向的值不会被刷新。应用程序可用WSAGetLastError()来获取失败的原因。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAENOTSOCK 描述字不是一个套接口。
WSA_INVALID_HANDLE WSAOVERLAPPED结构的hEvent域未包含一个有效的事件对象句柄。
WSA_INVALID_PARAMETER 有不可接受的参数。
WSA_IO_INCOMPLETE fWait假FALSE且输入/输出操作尚未完成。
另请参阅: WSACreateEvent(), WSAWaitForMultipleEvents(),WSARecv(), WSARecvFrom(), WSASend(), WSASendTo(),WSAConnect(), WSAAccept(), WSAIoctl().
7.10 WSAGetQoSByName()
简述:根据一个模板初始化QOS。
#include <winsock2.h>
BOOL WSAAPI WSAGetQOSByName( SOCKET s, LPWSABUF
lpQOSName, LPQOS lpQOS);
s:一个标识套接口的描述字。
lpQOSName:指定QOS模板的名字。
lpQOS:指向待填充QOS结构的指针。
返回值:
如果函数成功,返回真TRUE。如果函数失败,返回假FALSE。可调用WSAGetLastError()来获取进一步的错误信息。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAENOTSOCK 描述字不是一个套接口。
WSAEFAULT lpQOS参数不是用户地址空间的一个有效部分,或lpQOS的缓冲区太小。
WSA_INVAL 所指定的QOS模板名字非法。
另请参阅: WSAConnect(), WSAAccept(), getsockopt().
7.11 WSAHtonl()
简述:将一个以主机字节顺序表示的无符号长整形数转换为网络字节顺序。
#include <winsock2.h>
u_long WSAAPI WSAHtonl ( SOCKET s, u_long
hostlong );
s:一个标识套接口的描述字。
hostlong:一个用主机字节顺序表示的32位数。
返回值:WSAHtonl()返回以网络字节顺序表示的值。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAENOTSOCK 描述字不是一个套接口。
另请参阅: htonl(), htons(), ntohs(), ntohl(), WSAHtons(),WSANtohl(), WSANtohs().
7.12 WSAHtons()
简述:将一个以主机字节顺序表示的无符号短整形数转换为网络字节顺序。
#include <winsock2.h>
u_short WSAAPI WSAHtons (SOCKET sr, u_short
hostshort );
s:一个标识套接口的描述字。
hostshort:一个以主机字节顺序表示的16位数。
返回值:WSAHtons()返回以网络字节顺序表示的值。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAENOTSOCK 描述字不是一个套接口。
另请参阅: htonl(), htons(), ntohs(), ntohl(), WSAHtonl(),WSANtohl(), WSANtohs().
7.13 WSAIoctl()
简述:控制一个套接口的模式。
#include <winsock2.h>
int WSAAPI WSAIoctl(SOCKET s, DWORD
dwIoControlCode, LPVOID lpvInBuffer, DWORD
cbInBuffer, LPVOID lpvOutBuffer, DWORD
cbOutBuffer, LPDWORD lpcbBytesReturned,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE
lpCompletionRoutine);
s:一个套接口的句柄。
dwIoControlCode:将进行的操作的控制代码。
lpvInBuffer:输入缓冲区的地址。
cbInBuffer:输入缓冲区的大小。
lpvOutBuffer:输出缓冲区的地址。
cbOutBuffer:输出缓冲区的大小。
lpcbBytesReturned:输出实际字节数的地址。
lpOverlapped:WSAOVERLAPPED结构的地址。
lpCompletionRoutine:一个指向操作结束后调用的例程指针。
返回值:
调用成功后,WSAIoctl ()函数返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINVAL cmd不是一个合法的命令;或者一个输入参数非法;或者命令对于该种类型的套接口不适用。
WSAEINPROGRESS 在一个回调函数运行时调用了该函数。
WSAENOTSOCK 描述字不是一个套接口。
WSAEOPNOTSUPP 指定的ioctl命令无法实现,例如在SIO_SET_QOS或 SIO_SET_GROUP_QOS中指定的流描述无法实现。
WSA_IO_PENDING 一个重叠操作被成功启动,过后将报告完成情况。
WSAEWOULDBLOCK 套接口标志为非阻塞,且所需操作将产生阻塞。
另请参阅: socket(), ioctlsocket(), WSASocket(),setsockopt(), getsockopt().
7.14 WSAJoinLeaf()
简述:将一个叶节点加入一个多点会晤,交换连接数据,根据提供的流描述确定所需的服务质量。
#include <winsock2.h>
SOCKET WSAAPI WSAJoinLeaf ( SOCKET s, const struct
sockaddr FAR * name, int namelen, LPWSABUF
lpCallerData, LPWSABUF lpCalleeData,
LPQOS lpSQOS, LPQOS lpGQOS, int iFlags );
s:标识一个多点套接口的描述字。
name:将与套接口连接的远端名字。
namelen:名字长度。
lpCallerData:一个指针,指向多点会晤创建时传送给远端的用户数据。
lpCalleeData:一个指针,指向多点会晤创建时从远端传送回来的用户数据。
lpSQOS:一个指向套接口s的流描述的指针,每个方向一个。
lpGQOS:一个指向套接口组(如果存在)流描述的指针。
iFlags:标志位,用于指定套接口作为发送者。接收者或身兼二者。
返回值:若无错误发生,WSAJoinLeaf()返回新创建的多点套接口的描述字。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEADDRINUSE 指定的地址已经在使用中。
WSAEINTR 通过WSACancelBlockingCall()函数取消(阻塞)调用。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数。(参见B.3.6.6节)
WSAEALREADY 在指定的套接口上正在运行一个非阻塞的WSAJoinLeaf()调用。
WSAEADDRNOTAVAIL 本地主机无法获得指定的地址。
WSAEAFNOSUPPORT 所指定地址族中的地址无法与本套接口一起使用。
WSAECONNREFUSED 加入试图被强制拒绝。
WSAEFAULT name或namelen参数不是用户地址空间的一个有效部分;namelen参数太小;lpCalleeData、 lpSQOS和lpGQOS的缓冲区太小; lpCallerData缓冲区太大。
WSAEINVAL 套接口已与一个地址捆绑。
WSAEINVAL 套接口未与一个地址捆绑。
WSAEISCONN 套接口已是多点会晤的一个成员。
WSAENETUNREACH 当前无法从本主机联系网络。
WSAENOBUFS 无可用缓冲区空间。套接口无法加入。
WSAENOTSOCK 描述字不是一个套接口。
WSAEOPNOTSUPP lpSQOS和lpGQOS中所指定的流描述无法满足。
WSAEPROTONOSUPPORT 服务提供者不支持lpCallerData参数。
WSAETIMEDOUT 加入试图超时,未建立多点会晤。
WSAEWOULDBLOCK 套接口被标志为非阻塞,但多点会晤加入操作无法立即完成。当用select()选为读连接后,可使用select()对套接口进行操作。
另请参阅: accept(), bind(), select(), WSAAccept(),WSAAsyncSelect(), WSAEventSelect(), WSASocket().
7.15 WSANtohl()
简述:将一个以网络字节顺序表示的无符号长整形数转换为主机字节顺序。
#include <winsock2.h>
u_long WSAAPI WSANtohl ( SOCKET s, u_long netlong
);
s:一个标识套接口的描述字。
netlong:一个以网络字节顺序表示的32位数。
返回值:WSANtohl()返回一个以主机字节顺序表示的值。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAENOTSOCK 描述字不是一个套接口。
另请参阅: ntohl(), htonl(), htons(), ntohs(), WSAHtonl(),WSAHtons(), WSANtohs().
7.16 WSANtohs()
简述:将一个以网络字节顺序表示的无符号短整形数转换为主机字节顺序。
#include <winsock2.h>
u_short WSAAPI WSANtohs (SOCKET s, u_short
netshort );
s:一个标识套接口的描述字。
netshort:一个以网络字节顺序标识的16位数。
返回值:WSANtohs()返回以主机字节顺序表示的值。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAENOTSOCK 描述字不是一个套接口。
另请参阅: htonl(), htons(), ntohs(), ntohl(), WSAHtonl(),WSAHtons(), WSANtohl().
7.17 WSARecv()
简述:从一个套接口接收数据。
#include <winsock2.h>
int WSAAPI WSARecv ( SOCKET s, LPWSABUF lpBuffers,
DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd,
LPINT lpFlags, LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE
lpCompletionRoutine );
s:一个标识已连接套接口的描述字。
lpBuffers:一个指向WSABUF结构数组的指针。每一个WSABUF结构包含一个缓冲区的指针和缓冲区的长度。
dwBufferCount:lpBuffers数组中WSABUF结构的数目。
lpNumberOfBytesRecvd:如果接收操作立即结束,一个指向本调用所接收的字节数的指针。
lpFlags:一个指向标志位的指针。
lpOverlapped:一个指向WSAOVERLAPPED结构的指针(对于非重叠套接口则忽略)。
lpCompletionRoutine:一个指向接收操作结束后调用的例程的指针(对于非重叠套接口则忽略)。
返回值:
若无错误发生且接收操作立即完成,则WSARecv()函数返回所接收的字节数。如果连接结束,则返回0。请注意在这种情况下完成指示(启动指定的完成例程或设置一个事件对象)将早已发生。否则的话,将返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。错误代码WSA_IO_PENDING表示重叠操作成功启动,过后将有完成指示。任何其他的错误表示重叠操作未能成功地启动,以后也不会有完成指示。
如果设置了MSG_INTERRUPT标志,则返回值的含义变化。零表示成功,具体含义同上。否则的话,返回值直接包含如下所示