Winsock 的初始化

首先是调用 WSAStartup()
来加载合适的 Winsock Dll版本

其中两个参数

WORD wVersionRequested
加载库的版本
LPWSADATA lpWSAData
关于版本信息的结构体

typedef struct WSAData {
        WORD(_16)                    wVersion; 
 //winsocket的版本号
            //Windows XP 的版本是2.2
        WORD                    wHighVersion; //winsocket的最高版本
        char                    szDescription[WSADESCRIPTION_LEN+1]; //winsocket实现的句柄字符串
        char                    szSystemStatus[WSASYS_STATUS_LEN+1]; //winsocker的配置信息
        unsigned short          iMaxSockets; //最大socket数量,由系统资源决定,不确定
        unsigned short          iMaxUdpDg;  //通过WSAEnumProtocols()具体查询
        char FAR *              lpVendorInfo; //far 指针的长度是32位
            //near指针的长度是16位
            //#define FAR far

} WSADATA, FAR * LPWSADATA;

载入2.2版本得到的信息
wVersion:514
wHighVersion:514
szDescription:WinSock 2.0
szSystemStatus:Running
iMaxSockets:0
iMaxUdpDg:0

调用成功返回0,不成功返回10092
#define WSAVERNOTSUPPORTED      (WSABASEERR+92)

当完成了对socket的操作以后
应当调用 WSACleanup() 释放掉 winsock申请的资源.


Winsock 调用错误最常见的返回值的SOCKET_ERROR
#define SOCKET_ERROR            (-1)


如果调用winsock的函数出现错误 可以通过
WSAGetLastError()来取得对应的错误代码
注意:
WSAGetLastError()本身也是winsock的函数
所以要对其调用成功,必须先初始化winsock DLL

一个简单的Winsock DLL初始化 和 释放

#include
#include

using namespace std;

int main()
{
          WSADATA WSAData;
          int  ret;

          if( ret = WSAStartup(0x0, &WSAData) )
          {
                   cout << "Can not initilize winsock.dll" << endl;
                   cout << "Error Code:" << WSAGetLastError() << endl;
                   return 1;
           }
           else
           {
                   cout << "winsock.dll loded" << endl;
            }

           WSACleanup();
            //也应该检查该函数是否执行成功

           return 0;
}


初始化Winsock

什么是Winsock

    Winsock是Windows下的网络编程接口,它是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口。

构建编程环境

    Winsock在常见的Windows平台上有两个主要的版本,即Winsock1和Winsock2。编写与Winsock1兼容的程序你需要引用头文 件WINSOCK.H,如果编写使用Winsock2的程序,则需要引用WINSOCK2.H。此外还有一个MSWSOCK.H头文件,它是专门用来支持 在Windows平台上高性能网络程序扩展功能的。使用WINSOCK.H头文件时,同时需要库文件WSOCK32.LIB,使用WINSOCK2.H 时,则需要WS2_32.LIB,如果使用MSWSOCK.H中的扩展API,则需要MSWSOCK.LIB。正确引用了头文件,并链接了对应的库文件, 你就构建起编写WINSOCK网络程序的环境了。

初始化Winsock

    每个Winsock程序必须使用WSAStartup载入合适的Winsock动态链接库,如果载入失败,WSAStartup将返回SOCKET_ERROR,这个错误就是WSANOTINITIALISED,WSAStartup的定义如下:

int WSAStartup(
    WORD wVersionRequested,
    LPWSADATA lpWSAData
);

wVersionRequested指定了你想载入的Winsock版本,其高字节指定了次版本号,而低字节指定了主版本号。你可以使用宏 MAKEWORD(x, y)来指定版本号,这里x代表主版本,而y代表次版本。lpWSAData是一个指向WSAData结构的指针,WSAStartup会向该结构中填充其 载入的Winsock动态链
库的信息。

lpWSAData是一个指向WSAData结构的指针,WSAStartup会向该结构中填充其载入的Winsock动态链
库的信息。

lpWSAData是一个指向WSAData结构的指针,WSAStartup会向该结构中填充其载入的Winsock动态链
库的信息。

typedef struct WSAData 
{
    WORD           wVersion;
    WORD           wHighVersion;
    char           szDescription[WSADESCRIPTION_LEN + 1]; 
    char           szSystemStatus[WSASYS_STATUS_LEN + 1];
    unsigned short iMaxSockets;
    unsigned short iMaxUdpDg;
    char FAR *     lpVendorInfo;
} WSADATA, * LPWSADATA;

    wVersion为你将使用的Winsock版本号,wHighVersion为载入的Winsock动态库支持的最高版本,注意,它们的高字节代表次版本,低字节代表主版本。
    szDescription与szSystemStatus由特定版本的Winsock设置,实际上没有太大用处。
    iMaxSockets表示最大数量的并发Sockets,其值依赖于可使用的硬件资源。
    iMaxUdpDg表示数据报的最大长度;然而,获取数据报的最大长度,你需要使用WSAEnumProtocols对协议进行查询。
    最大数量的并发Sockets并不是什么神奇的数字,它是由可用的物理资源来决定的.
    lpVendorInfo是为Winsock实现而保留的制造商信息,这个在Windows平台上并没有什么用处.

    自Windows 95以后的操作系统都支持Winsock 2.2的版本.即使是这样,你也不能认为这些Windows平台支持最新的Winsock版本,为了让你的程序能够运行于大多数平台,最好使用Winsock1.1规范.
    
    当你使用完Winsock接口后,要调用下面的函数对其占用的资源进行释放:

    int WSACleanup(void);

    如果调用该函数失败也没有什么问题,因为操作系统为自动将其释放,对应于每一个WSAStartup调用都应该有一个WSACleanup调用.

错误处理
    
    Winsock函数调用失败大多会返回 SOCKET_ERROR(实际上就是-1),你可以调用WSAGetLastError得到错误的详细信息:

    int WSAGetLastError (void);

     对该函数的调用将返回一个错误码,其码值在WINSOCK.H或WINSOCK2.H(根据其版本)中已经定义,这些预定义值都以WSAE开头.同时你还可以使用WSASetLastError来自定义错误码值.

以下是一个使用上述知识初始化Winsock的一个例子(记得要引用Winsock的lib库).

#include

#include

void main(void)
{
   WSADATA wsaData;
    
     int Ret;

   // Initialize Winsock version 2.2

   if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
   {
      // NOTE: Since Winsock failed to load we cannot use 
      // WSAGetLastError to determine the specific error for
      // why it failed. Instead we can rely on the return 
      // status of WSAStartup.

      printf("WSAStartup failed with error %d\n", Ret);
      return;
   }

   // Setup Winsock communication code here

   // When your application is finished call WSACleanup
   if (WSACleanup() == SOCKET_ERROR)
   {
      printf("WSACleanup failed with error %d\n", WSAGetLastError());
   }
}

你可能感兴趣的:(网络编程)