为客户端创建套接字

初始化后,必须实例化 SOCKET 对象以供客户端使用。

创建套接字

  1. 声明包含 sockaddr 结构的 addrinfo 对象并初始化这些值。 对于此应用程序,未指定 Internet 地址系列,因此可以返回 IPv6 或 IPv4 地址。 应用程序将套接字类型请求为 TCP 协议的流套接字。

    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family   = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    
  2. 调用 getaddrinfo 函数,请求在命令行上传递的服务器名称的 IP 地址。 在此示例中,DEFAULT_PORT将客户端连接到的服务器上的 TCP 端口定义为 27015。 getaddrinfo 函数将其值作为检查错误的整数返回。

    #define DEFAULT_PORT "27015"
    
    // Resolve the server address and port
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }
    
  3. 创建名为 ConnectSocket 的 SOCKET 对象。

    SOCKET ConnectSocket = INVALID_SOCKET;
    
  4. 调用 套接字 函数并将其值返回到 ConnectSocket 变量。 对于此应用程序,请使用调用 getaddrinfo 返回的第一个 IP 地址,该地址与 hints 参数中指定的地址系列、套接字类型和协议相匹配。 在此示例中,指定了一个 TCP 流套接字,其套接字类型为 SOCK_STREAM,协议为 IPPROTO_TCP。 (AF_UNSPEC) 未指定地址系列,因此返回的 IP 地址可以是服务器的 IPv6 或 IPv4 地址。

    如果客户端应用程序只想使用 IPv6 或 IPv4 进行连接,则需要在 hints 参数中将地址系列设置为 AF_INET6 iPv6 或 IPv4 的 AF_INET。

    // Attempt to connect to the first address returned by
    // the call to getaddrinfo
    ptr=result;
    
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
        ptr->ai_protocol);
    
  5. 检查错误以确保套接字是有效的套接字。

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }
    

可以针对不同的实现更改传递给 套接字 函数的参数。

错误检测是成功网络代码的关键部分。 如果 套接字 调用失败,它将返回INVALID_SOCKET。 前面代码中的 if 语句用于捕获在创建套接字时可能发生的任何错误。 WSAGetLastError 返回与上次发生的错误关联的错误号。

注意

可能需要进行更广泛的错误检查,具体取决于应用程序。

例如,将 hints.ai_family 设置为 AF_UNSPEC 可能会导致连接调用失败。 如果发生这种情况,请改用特定的 IPv4 (AF_INET) 或 IPv6 (AF_INET6) 值。

WSACleanup 用于终止WS2_32 DLL 的使用。

下一步: 连接到套接字

与 Winsock 一起入门

初始化 Winsock

Winsock 客户端应用程序