WinSock2 sockaddr结构作为参数

时间:2014-03-20 00:39:43

标签: c++ sockets winsock winsock2

使用inet_ntop,WSAAddressToString,recvfrom等函数还需要提供实际sockaddr结构的大小还是要提供的地址族?

sockaddr结构的前两个字节表示地址族,因此也表明它实际上是sockaddr_in还是sockaddr_in6。

那么附加sizeof(sockaddr_in / sockaddr_in6)和AF_INET / AF_INET6的原因是什么?

1 个答案:

答案 0 :(得分:0)

sockaddr是遗留类型。特定地址系列有更新的sockaddr_...类型,例如IPv4的sockaddr_in和IPv6的sockaddr_in6,它们具有不同的字节大小。 API在通用sockaddr*指针上运行,部分原因在于历史原因,部分原因在于灵活性。套接字API识别多种地址类型。您通常必须提供大小,以便API可以验证您的内存缓冲区是否足够大,可以根据指定的系列传递地址数据(IPv4为AF_INET,IPv6为AF_INET6

inet_ntop()中,in_addrin6_addr不包含地址系列,这就是您必须单独传递它的原因。您有责任确保为传入的输入类型指定正确的地址系列。

WSAAddressToString()中,指向输入缓冲区的sockaddr*指针。您必须传递该缓冲区的已分配大小。例如,由于sockaddr_in小于sockaddr_in6,如果您分配sockaddr_in但将其系列设置为AF_INET6而不是AF_INET,则缓冲区太小对于访问所有IPv6字段的函数,它将失败并出现WSAEFAULT错误而不是崩溃。

recvfrom()中,sockaddr*是指向输出缓冲区的指针。您必须预先分配它并传递分配的大小。如果您分配sockaddr_in但收到IPv6数据包,则发件人的地址将不适合您的缓冲区,并且该函数将因WSAEFAULT错误而失败。