Winsock_API_基本函数

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

(VClink-ProjectOptions加入ws2_32.lib)4.4WinsockAPI基本函数——套接口与连接的建立4.4.1打开Winsock——WSAStartup(?)应用程序或DLL只能在一次成功的WSAStartup(?)调用之后才能进一步调用其他的WindowsSocketsAPI函数。1.函数格式WSAStartup(?)函数的格式如下:intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);2.函数参数说明wVersionRequested:此参数是一个WORD型(双字节型)数值,它指定准备在应用程序中要使用的Winsock库的版本号。其中,用高位字节指定副版本,用低位字节指定主版本。就目前的Win32平台而言,Winsock2库的最新版本是2.2(Win95为Winsock1.1)。如果需要加载Winsock2.2版,指定此参数的值为0x0202;也可使用宏MAKEWORD(X,Y),其中X为高位字节,Y为低位字节,如MAKEWORD(2,2)。lpWSAData:此参数是一个指向WSADATA结构的指针。当该函数被调用时,它返回关于WindowsSockets实现的详细信息,该结构的定义如下:typedefstructWSAData{WORDwVersion;WORDwHighVersion;CharszDescription[WSADESCRIPTION_LEN+1];CharszSystemStatus[WSASYS_STATUS_LEN+1];unsignedshortiMaxSockets;unsignedshortiMaxUdpDg;charFAR*lpVendorInfo;}WSADATA,FAR*LPWSADATA;各字段的含义说明如下:●wVersion:调用者希望使用的Winsock版本号;●wHighVersion:加载的Winsock库所支持的最高Winsock版本,??通常和wVersion的值相同;●szDescription:系统加载的Winsock库的说明字符串,如“Winsock2.0”;●szSystemStatus:系统状态或配置信息的说明字符串;●iMaxSockets:套接口的最大编号(该字段被Winsock2或其后的版本忽略);●iMaxUdpDg:UDP数据报的最大容量(该字段被Winsock2或其后的版本忽略);●lpVendorInfo:厂商专有信息(该字段被Winsock2或其后的版本忽略)。3.函数返回信息WSAStartup(?)函数的返回值是一个整数,如果调用成功则返回0。WSAStartup(?)函数调用不成功时返回如下的错误信息:●WSASYSNOTREADY:在Winsock的头文件Winsock2.h中,该错误代码定义的数值为10091,它表明加载的WinsockDLL不存在或底层的网络子系统无法使用。●WSAVERNOTSUPPORTED:该代码的数值为10092,所需的WindowsSocketsAPI的版本未由特定的WindowsSockets实现提供。?如果由wVersion返回的版本用户不能接受,则要调用WSACleanup(?)函数清除对Winsock的加载。●WSAEINVAL:该代码的数值为10022,说明应用程序指出的WindowsSockets版本不能被该WinsockDLL的实现所支持。●WSAEINPROGRESS:该代码的数值为10034,说明一个阻塞的Winsock调用正在进行中。●WSAEPROCLIM:该代码的数值为10047,说明已经达到了WindowsSockets实现所支持的任务数量的极限。●WSAEFAULT:该代码数值为10014,说明lpWSAData参数是一个无效的指针。注意:在这里为了便于大家理解错误代码,列出了给错误代码定义的数值。以后为了节省篇幅,不再列出错误代码的数值。如果要查询对应错误代码对应的数值,可以在Winsock的头文件Winsock.h或Winsock2.h中去查找。4.函数使用说明如果用户在没有正确加载WinsockDLL的情况下使用了其他的WinsockAPI函数,则被调用的函数返回WSANOTINITIALISED错误信息,代码为10093。该函数在程序中的基本使用方法如下:#includeWinsock2.h…//其他代码WORDwVersionRequested;WSADATAwsaData;wVersionRequested=MAKEWORD(2,2);if(WSAStartup(wVersionRequested,&wasData)!=0){//Winsock初始化错误//输出Winsock初始化错误提示信息,如“WSAStartupfailed”return;}//下面可以用两种方法中的任一种进行版本号匹配的检查//if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=0)if(wsaData.wVersion!=wVersionRequested){//Winsock版本号不匹配//输出Winsock版本号不匹配的错误提示信息;WSACleanup(?);return;}//说明WinsockDLL的加载正确,可以执行以下的其他代码…//其他程序代码结束对WinsockDLL库的使用时,一定要调用WSACleanup(?)函数卸载所加载的库。4.4.2创建套接口——socket(?)或WSASocket(?)应用程序在使用套接口通信前,必须要拥有一个套接口。使用socket(?)或WSASocket(?)函数来给应用程序创建一个套接口。1.函数格式在Winsock1中提供的创建套接口函数的格式如下:SOCKETsocket(intaf,inttype,intprotocol);在Winsock2中提供的该函数的扩展格式如下:SOCKETWSASocket(intaf,inttype,intprotocol,LPWSAPROTOCOL_INFOlpProtocolInfo,Groupg,intiFlags);2.函数参数说明以上两种格式中,前面三个参数的含义是一样的,说明如下:●af:该参数说明套接口要使用的协议地址族,地址族与协议族的含义相同。如果想建立一个UDP或TCP套接口,只能用常量AF_INET表示使用互联网协议(IP)地址。当然,Winsock2还支持其他的协议,但一般在程序中很少使用。●type:该参数描述套接口的协议类型。当第一个参数af是AF_INET时,它只能使用SOCK_STREAM、SOCK_DGRAM或SOCK_RAW三个协议类型中的任一个,分别表示要创建的是流式套接口、数据报套接口或原始套接口。●protocol:该参数说明该套接口使用的特定协议。当协议地址族af和协议类型type已经确定后,协议字段可以使用的值是限定的,如表4-1所示。如果调用者不希望特别指定所使用的协议,可以将此参数设置为0,系统就根据前两个参数的值自动确定一个协议字段的取值。以上三个参数就可以确定一个套接口,它们之间的对应关系可以用表4-1表示。表4-1套接口参数系统可以根据这三个参数建立一个套接口,并给它分配相应的资源,同时返回一个整型套接口号。因此,socket(?)函数调用实际上指定了相关五元组中的“协议”这一元。使用Winsock2时,一般可以先用WSAEnumProtocols(?)函数(该函数在第8章介绍),以获得系统所安装协议的相关信息。当然对现在的绝大部分用户来说,直接使用AF_INET(IP协议族)就可以了,因为几乎所有的协议实现系统都支持IP协议族。但要编写通用性好的应用程序时,最好还是先使用WSAEnumProtocols(?)函数查询一下系统安装的协议。在Winsock2提供的扩展格式中,增加了三个参数,其含义说明如下(因为常用的是格式1,所以这三个参数只需了解其大概的含义):协议地址族套接口类型套接口类型使用的值协议字段TCPSOCK_STREAMIPPROTO_TCPUDPSOCK_DGRAMIPPROTO_UDP互联网协议(IP)AF_INETRawsocketsSOCK_RAWIPPROTO_RAWIPPROTO_ICMP●lpProtocolInfo:一个指向WSAPROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。如果本参数不指向空(NULL),则前三个参数(af,type,protocol)被忽略,系统就根据该结构中三个字段的值确定套接口类型。●g:套接口组的描述字。组参数始终为0,因为目前尚无可支持套接口组的Winsock版本。●iFlags:套接口属性描述。iFlags可用参数如下:WSA_FLAG_OVERLAPPEDWSA_FLAG_MULTIPOINT_C_ROOTWSA_FLAG_MULTIPOINT_C_LEAFWSA_FLAG_MULTIPOINT_C_ROOFWSA_FLAG_MULTIPOINT_D_LEAF第一个标志WSA_FLAG_OVERLAPPED用于指定这个套接口具备重叠I/O(是适用于Winsock的通信模式之一)的特性。调用socket(?)建立一个套接字时,WSA_FLAG_OVERLAPPED便是默认设置。一般说来,在使用WSASocket时,最好始终保持设定该标志。后面4个标志用于处理多播套接口。3.函数返回信息该函数调用成功后,返回新创建的套接口号,它被定义成是一个无符号的整型数据。函数调用错误时返回INVALID_SOCKET,应用程序可进一步调用WSAGetLastError(?)函数来获取相应的错误代码。可能获得的错误代码说明如下:●WSANOTINITIALISED:在调用本API之前应成功调用WSAStartup(?);●WSAENETDOWN:网络子系统失效;●WSAEAFNOSUPPORT:不支持指定的地址族;●WSAEINPROGRESS:一个阻塞的Winsock调用正在进行中,或者服务提供者仍在处理一个回调函数;●WSAEMFILE:无可用的套接口描述字;●WSAENOBUFS:无可用的缓冲区空间,套接口无法创建;●?WSAEPROTONOSUPPORT:不支持指定的协议;●?WSAEPROTOTYPE:指定的协议对于本套接口类型错误;●?WSAESOCKTNOSUPPORT:本地址族不支持指定的套接口类型;●?WSAEINVAL:g参数非法。4.函数使用说明要创建一个流套接口时,可以使用下列三种格式之一:SOCKETsockid=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);SOCKETsockid=WSASocket(AF_INET,SOCK_STREAM,0);SOCKETsockid=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);要创建一个数据报套接口时,其格式如下(为节省篇幅,两种套接口的创建只给出了一种格式):SOCKETsockid=socket(AF_INET,SOCK_GDRAM,IPPROTO_UDP);要创建一个原始套接口时,其格式如下:SOCKETsockid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);4.4.3指定本地地址——bind()当用socket()创建了一个套接口后,该套接口还是不能直接使用,因为它只存在于一个名字空间(地址族)中,也就是说它只确定了通信所希望使用的服务类型,并没有与该主机上提供服务的某端口联系在一起,这样的套接口可以叫未命名的套接口。bind()函数通过给一个未命名的套接口分配一个本地名字来为套接口建立本地捆绑,即把一个套接口与一个主机地址和端口号联系起来。本函数适用于数据报或流类套接口。1.函数格式bind(

1 / 21
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功