zoukankan      html  css  js  c++  java
  • 【网络编程】之一、初识WinSocket

      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网络程序的环境了。


    OK,下面我们来看看具体用法:

    初始化winsocket

    每个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动态链库的信息。

    typedef struct WSAData 
    {
        WORD           wVersion;       //wVersion为你将使用的Winsock版本号
        WORD           wHighVersion;//wHighVersion为载入的Winsock动态库支持的最高版本,
    注意,它们的高字节代表次版本,低字节代表主版本。
        char           szDescription[WSADESCRIPTION_LEN + 1]; 
        char           szSystemStatus[WSASYS_STATUS_LEN + 1];//上面两个变量由特定版本的Winsock设置,实际上没有太大用处。
        unsigned short iMaxSockets;//表示最大数量的并发Sockets,其值依赖于可使用的硬件资源。
        unsigned short iMaxUdpDg;// iMaxUdpDg表示数据报的最大长度
        char FAR *     lpVendorInfo;//是为Winsock实现而保留的制造商信息,
    这个在Windows平台上并没有什么用处.
    } WSADATA, * LPWSADATA; 

    当你使用完Winsock接口后,要调用下面的函数对其占用的资源进行释放:
        int WSACleanup(void);
    如果调用该函数失败也没有什么问题,因为操作系统为自动将其释放,对应于每一个WSAStartup调用都应该有一个WSACleanup调用.

    错误处理:

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

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


    代码示例:

    下面是来自msdn的示例:

    #define WIN32_LEAN_AND_MEAN
    
    #include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>
    
    // Need to link with Ws2_32.lib
    #pragma comment(lib, "ws2_32.lib")
    
    
    int __cdecl main()
    {
    
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
    
    /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
        wVersionRequested = MAKEWORD(2, 2);
    
        err = WSAStartup(wVersionRequested, &wsaData);
        if (err != 0) {
            /* Tell the user that we could not find a usable */
            /* Winsock DLL.                                  */
            printf("WSAStartup failed with error: %d\n", err);
            return 1;
        }
    
    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */
    
        if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
            /* Tell the user that we could not find a usable */
            /* WinSock DLL.                                  */
            printf("Could not find a usable version of Winsock.dll\n");
            WSACleanup();
            return 1;
        }
        else
            printf("The Winsock 2.2 dll was found okay\n");
            
    
    /* The Winsock DLL is acceptable. Proceed to use it. */
    
    /* Add network programming using Winsock here */
    
    /* then call WSACleanup when done using the Winsock dll */
        
        WSACleanup();
    
    }

    这里只是初识winsocket!大概了解一下!

    2012/8/14

    jofranks 于南昌


  • 相关阅读:
    curl查询公网出口IP
    Linux scp命令
    docker 安装 MySQL 8.0
    Ubuntu下apt方式安装与更新Git
    第2章 一切都是对象
    Mave实战(1)——Maven介绍
    关于Identityserver4和IdentityServer3 授权不兼容的问题
    装箱和拆箱、类型比较
    接口自动化用例(Fitnesse)中批量获取系统链路日志
    man时括号里的数字是啥意思
  • 原文地址:https://www.cnblogs.com/java20130723/p/3211415.html
Copyright © 2011-2022 走看看