winsock编程(二)

 二.WSAStartup函数
Windows sockets函数WSAStartup对进程初始化WS2_32.DLL的使用。

int WSAStartup(

WORD wVersionRequested,

LPWSADATA lpWSAData

);

参数:
wVersionRequested

[in]windows sockets支持调用者能使用的最高版本。高位标出了次版本,低位标出了主版本。

lpWSAData

[out]一个指向WSAData的指针,用来获取windows socket的实际的详细信息。

注意
WSAStartup必须是第一个被程序或者DLL调用的windows sockets函数。它允许程序或者DLL确定使用的windows sockets版本,并且返回实际的windows sockets版本。程序或者DLL必须在调用WSAStartup调用成功后才能调用其他windows sockets函数。

为了支持高版本的windows sockets实现,以及功能上和当前sockets版本不同的应用程序,WSAStartup定义了一些规则。应用程序、WSAStartup和WS2_32.DLL指出它们能支持的最高版本,并确认对方的最高版本是可接受的。在调用WSAStartup时,WS2_32.DLL检查程序所需要的版本。若版本比DLL所支持的最低版本要高,则调用成功,DLL在wHighedVersion存储返回它支持的最高版本,wVersion中返回最小版本支持和请求的wVersionRequested。若WSAData的wVersion字段对于应用程序不能使用,应该调用WSACleanup或者寻找其他的DLL或者直接报告错误消息。

程序可以请求一个比当前规范更高的版本,这种情况下,程序只能使用高版本中的功能。为了适应未来的版本,程序应该完全的适应未来的版本,例如重新编译,链接一个新的DLL,或者其他的情况。

下面的规则允许WS2_32.DLL和windows sockets程序支持一个范围的windows sockets版本。若存在一个版本重叠,则程序能调用一定范围版本的WS2_32.DLL。下图给出了WSAStartup在DLL版本和给定的版本之间的一些选择结果:

DLLVersion 程序要求 选择结果

1.1 1.1 1.1

1.0 1.1 1.0

1.0 1.1 1.0 1.0

1.0 1.1 1.1 1.1

1.0 1.1 调用失败

1.1 1.0 不支持

1.1 2.0 1.1

2.0 2.0 2.0

下面的实例代码演示了程序怎样调用WSAStartup来支持2.2版本的DLL:

WORD wVersionRequested;

WSAData wsaData;

int err;


wVersionRequested = MAKEWORD(2,2);


err=WSAStartup(wVersionRequested,&wsaData);

if(err!=0){

return;

}


if(LOBYTE(wsaData.wVersion)!=2||

HIBYTE(wsaData.wVersion)!=2){

WSACleanup();

return;

}


//开始使用windows sockets。

一旦程序或者DLL成功调用了WSAStartup,就可以调用其他的windows sockets函数了。在使用完WS2_32.DLL后,程序或者DLL应该调用WSACleanup来释放资源。

更多的windows sockets描述在WSAData结构中。

一个程序或者DLL可以多次调用WSAStartup若它需要多次获得WSAData信息。每次的调用都能确定一个DLL支持的版本号。

程序必须在每次成功调用WSAStartup后调用WSACleanup,以便第三方的DLL确定是否程序还在使用DLL。这意味着若程序调用了三次WSAStartup,它也必须调用三次WSACleanup。前两次什么也没做,只是减少了DLL的引用计数器,最后一次WSACleanup通知进程做一些必要的资源清理和释放工作。

返回值
若调用成功,WSAStartup返回0。否则,它返回下列的错误代码。

当WSAStartup调用失败时,程序不能使用WSAGetLastError检查最后的错误代码。因为WS2_32.DLL在这种情况下不会加载,所以客户端区的“最后的错误”并不能建立。

错误码
WSASYSNOTREADY 底层网络系统还没有准备好通信。

WSAVERNOTSUPPORTED windows sockets不支持的请求的版本

WSAEINPROCESS 1.1版本正在运行

WSAEPROCLIM 支持的任务已经达上限。

WSAEFAULT lpWSAData不是一个可识别的版本。

三.WSACleanup函数
windows sockets函数WSACleanup终止WS2_32.DLL的使用。

int WSACleanup(void);

注意
在调用其他windows sockets函数之前,程序必须成功调用WSAStartup函数。当它完成windows sockets的使用后,程序必须调用WSACleanup反注册并释放占用的资源。一个未决的阻塞,或者线程的异步调用,都能不发送消息或者标记事件对象而终止。任何重叠的发送和接受操作也能被取消。在这种情况下,运行中的操作退出,并返回错误码WSA_OPERATION_ABORTED。

在调用WSACleanup时分配的socket会复位并自动清除,就好像调用了closesocket一样。已经调用了closesocket的socket,但还在传送数据,也会受到影响――当WS2_32.DLL从内存中卸载时数据会丢失。为了确保所有数据都传送完毕,请调用shutdown来关闭连接,这样在数据传送完毕后就会调用closesocket和WSACleanup。所有的资源和状态,譬如未发送的消息队列,也应该卸载,这样下一个用户就才可以使用。

在调用WSAStartu后必须调用WSACleanup。之后最后一次WSACleanup做实际的清扫工作,其他的调用仅仅是减少WS2_32.DLL的引用计数。

返回值
若函数调用成功则返回0。否则,返回SOCKET_ERROR,可以用WSAGetLastError获取一个错误代码。

试着从一个悬挂程序调用WSACleanup,并不能获取一个返回值是一个常见的错误。当程序需要退出而有阻塞的进程时,必须先调用WSACancelBlockingCall使控制权交给程序后,再调用WSACleanup。

在多线程程序中,WSACleanup终止所有线程的所有操作。

错误码
WSANOTINITIALISED 在调用WSACleanup前必须成功调用WSAStartup。

WSAENETDOWN 网络子系统错误。

WSAEINPROGRESS 有阻塞的线程或者回调函数正在处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值