为客户端创建套接字
初始化后,必须实例化 SOCKET 对象以供客户端使用。
创建套接字
声明包含 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;
调用 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; }
创建名为 ConnectSocket 的 SOCKET 对象。
SOCKET ConnectSocket = INVALID_SOCKET;
调用 套接字 函数并将其值返回到 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);
检查错误以确保套接字是有效的套接字。
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 的使用。
下一步: 连接到套接字
相关主题