WSAStartup与WSACleanup
WSAStartup应该与WSACleanup成对使用,WSAStartup的功能是初始化Winsock DLL,WSACleanup是来解除与Socket库的绑定并且释放Socket库所占用的系统资源。

在Windows下,Socket是以DLL的形式实现的。在DLL内部维持着一个计数器,只有第一次调用WSAStartup才真正装载DLL,以后的 调用只是简单的增加计数器,而WSACleanup函数的功能则刚好相反,每调用一次使计数器减1,当计数器减到0时,DLL就从内存中被卸载!因此,你 调用了多少次WSAStartup,就应相应的调用多少次的WSACleanup.

WSAStartup()简述:
#include <winsock.h>

int PASCAL FAR WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );

wVersionRequested Windows Sockets API提供的调用方可使用的最高版本号.高位字节指出副版本(修正)号,低位字节指明主版本号.
lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节.

注释:
本函数必须是应用程序或DLL调用的第一个Windows Sockets函数.它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节.应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数.
为支持日后可能和Windows Sockets 1.1有功能上差异的Windows Sockets实现及应用程序,在WSAStartup()中规定了一个协议.WSAStartup()的调用方和Windows Sockets DLL互相通知对方它们可以支持的最高版本,并且互相确认对方的最高版本是可接受的. 在WSAStartup()函数的入口,Windows Sockets DLL检查了应用程序所需的版本.如果版本高于DLL支持的最低版本,则调用成功并且DLL在wHighVersion中返回它所支持的最高版本,在 wVersion中返回它的高版本和wVersionRequested中的较小者.然后Windows Sockets DLL就会假设应用程序将使用wVersion.如果WSDATA结构中的wVersion域对调用方来说不可接收, 它就应调用WSACleanup()函数并且要么去另一个Windows Sockets DLL中搜索,要么初始化失败.
本协议允许Windows Sockets DLL和Windows Sockets应用程序共同支持一定范围的Windows Sockets版本.如果版本范围有重叠,应用程序就可以成功地使用Windows Sockets DLL.下列的图表给出了WSAStartup()在不同的应用程序和Windows Sockets DLL版本中是如何工作的:

应用程序版本 DLL版本 wVersionRequested wVersion wHighVersion 最终结果
1.1                    1.1            1.1                                 1.1            1.1                      use 1.1
1.0 1.1 1.0 1.1 1.0 1.0 use 1.0
1.0 1.0 1.1 1.0 1.0 1.1 use 1.0
1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 1.0 1.1 1.0 1.0 失败
1.0 1.1 1.0 -- -- WSAVERNOTSUPPORTED
1.0 1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 2.0 1.1 2.0 1.1 1.1 use 1.1
2.0 1.1 2.0 1.1 1.1 失败

下列代码段给出了只支持Windows Sockets 1.1版本的应用程序是如何进行WSAStartup()调用的:

WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
return;
}

/* Confirm that the Windows Sockets DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
WSACleanup( );
return;
}

/* The Windows Sockets DLL is acceptable. Proceed. */

下面的代码段示例了只支持1.1版的Windows Sockets DLL是如何进行WSAStartup()协商的:

/* Make sure that the version requested is >= 1.1. */
/* The low byte is the major version and the high */
/* byte is the minor version. */

if ( LOBYTE( wVersionRequested ) < 1 ||
( LOBYTE( wVersionRequested ) == 1 &&
HIBYTE( wVersionRequested ) < 1 ) {
return WSAVERNOTSUPPORTED;
}

/* Since we only support 1.1, set both wVersion and */
/* wHighVersion to 1.1. */

lpWsaData->wVersion = MAKEWORD( 1, 1 );
lpWsaData->wHighVersion = MAKEWORD( 1, 1 );

一旦应用程序或DLL进行了一次成功的WSAStartup()调用,它就可以继续进行其它所需的Windows Sockets API调用.当它完成了使用该Windows Sockets DLL的服务后,应用程序或DLL必须调用WSACleanup()以允许Windows Sockets DLL释放任何该应用程序的资源.
实际的Windows Sockets实现细节在WSAData结构中描述如下:

struct WSAData {
WORD wVersion;
WORD wHighVersion;
char
szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYSSTATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
};

该结构的成员为:
成员 用法
wVersion Windows Sockets DLL期待调用方使用的Windows Sockets规范的版本.
wHighVersion DLL可支持的Windows Sockets规范的最高版本.通常它和wVersion相同.
szDescription 一个null结尾的ASCII字串,Windows Sockets DLL将Windows Sockets实现的说明及厂商描述拷至该串.这段文本(长度最多256个字符)可能包含任何字符, 但厂家注意到不把控制和格式字符包含进去:该字串的最可能用法就是在状态消息中显示.
szSystemStatus 一个null结尾的ASCII字串,Windows Sockets DLL将相关的状态和配置信息拷至该串.Windows Sockets DLL只有在该信息对用户或支撑人员有用时才会使用该域:它不应该被认为是szDescription域的扩展.
iMaxSockets 一个进程可以打开的最大套接口数目.Windows Sockets的实现可以提供一个全局的套接口池给任何进程分配;也可以为每个进程分配套接口资源.该数字可反映出Windows Sockets DLL或网络软件是如何配置的.应用程序员可以使用该数字作为该Windows Sockets实现是否可以被应用程序使用的原始依据.例如,一个X Windows服务器可能在它启动时检查iMaxSockets:若它小于8,应用程序应显示一条错误信息, 让用户重新配置网络软件.(这是szSystemStatus可能使用到的一种情况.)显然,并不保证一个特定的应用程序可以实际分配到 iMaxSockets个套接口,因为可能有其它的Windows Sockets应用程序在使用.
iMaxUdpDg 以字节表示的可由Windows Sockets应用程序发送或接收的最大UDP数据报的大小.如果应用程序没有给出限制,iMaxUdpDg为0.在Berkeley套接口的许多实现 中,对于UDP数据报的导向有一个隐含的限制8192字节.Windows Sockets的实现可以在分配碎片重组缓冲区的基础上给出界限.对于一般的Windows Sockets实现iMaxUdpDg的最小值为512.注意不考虑iMaxUdpDg的值,而试图在网络上发送一个大于最大传输单元(MTU)的广播数 据报是不明智的.(Windows Sockets API没有提供发现MTU的机制,但它必须不小于512字节.)
lpVendorInfo 指向厂商规定数据结构的远指针.该结构的定义(如果提供)超出了本规范的范围.

应用程序或DLL若需要多次得到WSAData结构信息,就必须多次调用WSAStartup().然而,wVersionRequired参数假设在所 有调用WSAStartup()中都相同;也就是,应用程序或DLL不能在第一次调用WSAStartup()后改变Windows Sockets的版本号.
对应于每一次WSAStartup()调用必须有一个WSACleanup()调用,以使第三级(third-party)DLL可以利用和应用程序相关 的Windows Sockets DLL.这意味着,例如,如果应用程序调用了WSAStartup()三次,它就必须调用WSACleanup()三次.对WSACleanup()的前 两次调用除了减少内置计数器以外不做任何事, 对任务的最后一次WSACleanup()调用为任务释放了所有所需的资源.

返回值:
0 成功.
否则返回下列的错误代码之一.注意通常依靠应用程序调用WSAGetLastError()机制获得的错误代码是不能使用的,因为Windows Sockets DLL可能没有建立"上一错误"信息储存的客户数据区域.

关于Windows Sockets提供者的说明:
每一个Windows Sockets应用程序必须在进行其它Windows Sockets API调用前进行WSAStartup()调用.这样,本函数就可以用于初始化的目的.
进一步的说明在WSACleanup()的说明中有讨论.

错误代码:
WSASYSNOTREADY 指出网络通信依赖的网络子系统还没有准备好.
WSAVERNOTSUPPORTED 所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供.
WSAEINVAL 应用程序指出的Windows Sockets版本不被该DLL支持.

参见:
send(), sendto(), WSACleanup()

WSAStartup与WSACleanup相关推荐

  1. Socket程序从windows移植到linux下需要注意的

    )头文件 windows下winsock.h或winsock2.h linux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in. ...

  2. TCP/IP学习入门笔记

    近期需要做一个用到UDP的工程,之前的情况是上位机计算出的车速(左右轮速),发送给各个小车(具体实现还不知道,等下去问硬件的同学),现在我们要改成用WIFI通信,大致的想法是:以后电脑和小车都连接好手 ...

  3. 通用异步 Windows Socket TCP 客户端组件的设计与实现

    编写 Windows Socket TCP 客户端其实并不困难,Windows 提供了6种 I/O 通信模型供大家选择.但本座看过很多客户端程序都把 Socket 通信和业务逻辑混在一起,剪不断理还乱 ...

  4. WinSock网络编程实用宝典(一)

    一.TCP/IP 体系结构与特点    1.TCP/IP体系结构   TCP/IP协议实际上就是在物理网上的一组完整的网络协议.其中TCP是提供传输层服务,而IP则是提供网络层服务.TCP/IP包括以 ...

  5. WinSock编程基础

    在上一篇中,我们具体介绍了socket的相关概念,本节将概述套接字规范及操作的一些基础性知识.   一.套接字的一些基础知识 1.Windows通信相关驱动 netio.sys(Network I/O ...

  6. 关于 AfxSocketInit() 的使用

       一般来说 WASAtarup() 是应用程序调用的windows sockets dll的第一个函数,在调用任何winsock api之前,必须调用wsastartup()进行初始化,最后调用W ...

  7. Winsock网络编程快速入门

     一.基本知识 1.Winsock,一种标准API,一种网络编程接口,用于两个或多个应用程序(或进程)之间通过网络进行数据通信.具有两个版本: Winsock 1: Windows CE平台支持. ...

  8. Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)

    Qt实现Winsock网络编程-TCP服务端和客户端通信(多线程) 前言 感觉Winsock网络编程的api其实和Linux下网络编程的api非常像,其实和其他编程语言的网络编程都差不太多.博主用Qt ...

  9. WinSock网络编程基础(1)

    记录学习windows网络编程过程中遇到的问题和相关笔记 基本概念: Socket: socket起源于UNIX,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.基于&qu ...

最新文章

  1. Android下PopupWindow隐藏及显示(showAtLocation/showAsDropDown)
  2. net start zabbix agent 服务没有相应控制功能_zabbix-基础系列(十七)--实战之监控 php-fpm...
  3. 阿里云定时任务并自动释放
  4. Greenplum roaring bitmap与业务场景 (类阿里云RDS PG varbitx, 应用于海量用户 实时画像和圈选、透视)
  5. linux 查看socket fd,linux socket中select()函数以及FD_ZERO FD_SET FD_CLR FD_ISSET
  6. 边缘检测之Canny
  7. 使用解码逻辑创建YOLO Core ML对象检测器(四)
  8. 经过多次试验后第一个成功地实现 HTTPService 与 MXML 之间传递数据,ArrayCollection 与DataGrid 之间成功绑定...
  9. Mini-Batch 、Momentum、Adam算法的实现
  10. 服务器系统能装cad吗,服务器主机用CAD画图吗
  11. win10很多软件显示模糊_Windows 10系统中屏幕字体变模糊,用这3个方法快速解决!...
  12. unix时间戳 为什么计算机时间要从1970年1月1日开始算起?
  13. 虚拟化VMware简介5——DRS 与 DPM 详解
  14. 面试时被问“你的缺点是什么?”,这么答就对了
  15. mysql数据库误删且未持久化_MySQL恢复误删数据解决方案
  16. 【Matlab】删除cell中所有的空白cell
  17. 网络游戏私服行业现状和反私服的措施
  18. 分享tiny4412,emmc烧录u-boot, 支持fastboot模式烧写emmc
  19. AsyncTask使用以及源码分析
  20. arrays shot JAVA_Apache Flink 1.3-SNAPSHOT 中文文档: Java 8

热门文章

  1. 科技创新变革全新趋势
  2. html galgame引擎,GitHub - kasuganosora/Reitsuki: Html5 GalGameEngine
  3. 改进后的第二版Retropie树莓派掌机(三)
  4. 如果你喜欢波点的活力
  5. OpenCV-Python learning-2.视频、相机简单处理
  6. 线性规划之单纯形法【超详解+图解】
  7. 在银河麒麟上编译运行firefox
  8. 专访阿里王贤:我所理解的网站架构
  9. 三毛6-- 沙漠观浴记
  10. 湖北考研调剂计算机信息,【计算机考研调剂】2018年湖北工业大学非全日制考研调剂公告...