为服务器创建套接字
初始化后,必须实例化 SOCKET 对象以供服务器使用。
为服务器创建套接字
getaddrinfo 函数用于确定 sockaddr 结构中的值:
- AF_INET 用于指定 IPv4 地址系列。
- SOCK_STREAM 用于指定流套接字。
- IPPROTO_TCP 用于指定 TCP 协议 。
- AI_PASSIVE 标志指示调用方打算在 调用绑定 函数时使用返回的套接字地址结构。 如果设置了 AI_PASSIVE 标志,并且 getaddrinfo 函数的 nodename 参数为 NULL 指针,则套接字地址结构的 IP 地址部分将设置为 IPv4 地址的 INADDR_ANY,或 iPv6 地址的 IN6ADDR_ANY_INIT。
- 27015 是与客户端将连接到的服务器关联的端口号。
addrinfo 结构由 getaddrinfo 函数使用。
#define DEFAULT_PORT "27015" 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; hints.ai_flags = AI_PASSIVE; // Resolve the local address and port to be used by the server iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed: %d\n", iResult); WSACleanup(); return 1; }
为服务器创建名为 ListenSocket 的 SOCKET 对象,以侦听客户端连接。
SOCKET ListenSocket = INVALID_SOCKET;
调用 套接字 函数并将其值返回到 ListenSocket 变量。 对于此服务器应用程序,请使用调用 getaddrinfo 返回的第一个 IP 地址,该地址与 hints 参数中指定的地址系列、套接字类型和协议匹配。 在此示例中,请求了 IPv4 的 TCP 流套接字,地址系列为 IPv4,套接字类型为 SOCK_STREAM,协议为 IPPROTO_TCP。 因此,为 ListenSocket 请求 IPv4 地址。
如果服务器应用程序想要侦听 IPv6,则需要在 hints 参数中将地址系列设置为 AF_INET6。 如果服务器想要同时侦听 IPv6 和 IPv4,则必须创建两个侦听套接字,一个用于 IPv6,另一个用于 IPv4。 应用程序必须单独处理这两个套接字。
Windows Vista 和更高版本提供创建单个 IPv6 套接字的功能,该套接字置于双堆栈模式以侦听 IPv6 和 IPv4。 有关此功能的详细信息,请参阅 双堆栈套接字。
// Create a SOCKET for the server to listen for client connections ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
检查错误以确保套接字是有效的套接字。
if (ListenSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; }
下一步: 绑定套接字
相关主题