• windows 网络编程[转]


    利用winsock编写网络应用程序服务端的步骤简述如下
    WSAStartup 初始化网络编程库
    socket 创建套接字
    bind 指定地址、端口,绑定套接字
    listen 进入监听状态
    accept 等待接收新连接
    send/recv 收发数据
    closesocket 关键套接字
    WSAStartup 释放对动态库的使用

    下面详细介绍各API
    1. Winsock初始化
    调用int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData )函数
    WSAStartup,即WSA(Windows SocKNDs Asynchronous,Windows异步套接字)的启动命令。是Windows下的网络编程接口软件Winsock1 或 Winsock2 里面的一个命令(Ps:Winsock 是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口)。
    为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。

    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested=MAKEWORD(2,2);

    if(WSAStartup(wVersionRequested,&wsaData)!=0)
    {

    //初始化失败

    }

    if(wsaData.wVersion != wVersionRequested)
    {

    //版本不匹配

    }

    2. 创建套接字

    int socket(int domain, int type, int protocol);
    函数说明:
    第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET;
    第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部);
    第三个参数指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。
    返回值:成功返回套接字描述符,否则返回INVALID_SOCKET。

    例子:
    if ((m_sk = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {

    //创建套接字失败

    }

    3. 绑定套接字

    地址结构的定义:

    /*

    * Socket address, internet style.

    */
    struct sockaddr_in {
    short sin_family; //协议族
    u_short sin_port; //端口号
    struct in_addr sin_addr; //地址信息
    char sin_zero[8];
    };

    /*
    * Internet address (old style... should be updated)
    */
    struct in_addr {
    union {
    struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
    struct { u_short s_w1,s_w2; } S_un_w;
    u_long S_addr;
    } S_un;

    #define s_addr S_un.S_addr

    /* can be used for most tcp & ip code */

    /*

    * Structure used by kernel to store most

    * addresses.

    */

    struct sockaddr {

    u_short sa_family; /* address family */

    char sa_data[14]; /* up to 14 bytes of direct address */

    };

    注意:s_addr是一个宏,可以方便设置地址

    #define s_addr  S_un.S_addr
                                    /* can be used for most tcp & ip code */
    /*
         * Structure used by kernel to store most
         * addresses.
    */
    struct sockaddr {
            u_short sa_family;              /* address family */
            char    sa_data[14];            /* up to 14 bytes of direct address */
    };
    注意:s_addr是一个宏,可以方便设置地址
    上述定义在winsock2.h中
    绑定函数原型:
    int bind( int sockfd , const struct sockaddr * my_addr, socklen_t addrlen);
    函数说明:
    参数列表中,sockfd 表示已经建立的socket编号(描述符);
      my_addr 是一个指向sockaddr结构体类型的指针;
    参数addrlen表示my_addr结构的长度,可以用sizeof函数获得。

    例子:
    sockaddr_in addr;
        addr.sin_family = AF_INET; //使用互联网际协议,即IP协议
        addr.sin_port = htons(port);
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    IP地址参数为INADDR_ANY,则由系统内核来自动指定
    port为0,则由系统自动指派一个1024~5000之间惟一的端口号

    if (bind(m_sk, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
    {
        //绑定出错
    }

    4. 进入监听状态

    int listen(int s, int backlog);
    函数说明:
    s:已绑定的套接字
    backlog:同时能处理的最大连接数
    Listen()并未开始接收连线, 只是设置socket 为listen 模式, 真正接收client 端连线的是accept(). 通常listen()会在socket(), bind()之后调用, 接着才调用accept()。

    5. 接受连接

    int accept(int s,struct sockaddr * addr,int * addrlen); 
    当有新的连接到来时,accept返回一个新的套接字描述符。连接请求端的相关信息存储在addr中。
    参数sockfd
    参数sockfd是监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,它只知道一个地址和一个端口号。
    参数addr
    这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址,当然这个地址是通过某个地址结构来描述的,用户应该知道这一个什么样的地址结构。如果对客户的地址不感兴趣,那么可以把这个值设置为NULL。
    参数len
    也是结果的参数,用来接受上述addr的结构的大小的,它指明addr结构所占有的字节个数。同样的,它也可以被设置为NULL。

    如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的套接字来完成与客户的通信

    6. 收发数据

    int send(int s, const void *buf, int len, int flags);
    int recv(int s, void *buf, int len, int flags);
    函数返回实际收发的字节数。出错返回-1, 需要关闭此连接。
    函数缺省是阻塞函数,直到发送/接收完成。
    注意:如果send 函数返回值与参数len 不相等,则剩余的未发送信息需要再次发送
    recv接收到数据之后不会在末尾添加’’。

    7. 其它API

    WSAGetLastError()
    获取上次失败操作的错误状态
    closesocket(int socket)
    关闭套接字
    WSACleanup()
    终止Winsock 2 DLL (Ws2_32.dll) 的使用

  • 相关阅读:
    (三)3-5 Python生成式和生成器
    (三)3-4 Python的高阶函数和匿名函数
    Linux下安装Python3
    Python math函数库
    今日头条as,cp,_signature参数破解
    使用scrapy实现分布式爬虫
    scrapy框架持久化存储
    Python中使用rsa加密
    使用Python进行微博登录
    WebDriverWait 显示等待
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/4516827.html
Copyright © 2020-2023  润新知