windows winsock2 socket从WSAGetLastError返回10014 WSAEFAULT(ipv4 / ipv6相关)

Posted

技术标签:

【中文标题】windows winsock2 socket从WSAGetLastError返回10014 WSAEFAULT(ipv4 / ipv6相关)【英文标题】:windows winsock2 socket return 10014 WSAEFAULT from WSAGetLastError (ipv4 / ipv6 related) 【发布时间】:2016-02-20 20:27:11 【问题描述】:

重现步骤:

    创建 IPv6 套接字 AF_INET6/SOCK_DGRAM/UDP 将套接字绑定到 IPv6 地址 使用 sendto(...) winsocket API 但指定 IPv4 要发送到的套接字 AF_INET 系列地址地址

Winsock2 API 将返回带有 WSAGetLastError 的 WSAEFAULT。

【问题讨论】:

更好的方法是为 family 参数指定 AF_INET6,并使用 sockaddr_in6,但在该结构中放置 IPv4 映射的 IPv6 地址(如此处所述:tcpipguide.com/free/t_IPv6IPv4AddressEmbedding-2.htm)。这为您提供了一个 IPv6 套接字,它仍然通过 IPv4 进行通信,并且运行良好。 【参考方案1】:

如果您尝试使用 IPv6 套接字将 UDP 数据包发送到 IPv4 地址,sendto() 将报告 WSAEFAULT 错误。此行为由 MSDN 描述:

sendto function

返回值

如果没有发生错误,sendto 返回发送的总字节数,可以小于 len 指示的数字。否则,返回 SOCKET_ERROR 的值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

...

WSAEFAULT buf 或 to 参数不是用户地址空间的一部分,或 tolen 参数太小

技术上确实如此,因为 IPv4 地址小于 IPv6 地址。当 sizeof 实际上是使用了错误的地址族时,认为 sizeof 错误可能有点误导,因此 sizeof 表示使用的大小错误。

在此处另见 windows 错误代码:

Windows Sockets Error Codes

【讨论】:

以上是关于windows winsock2 socket从WSAGetLastError返回10014 WSAEFAULT(ipv4 / ipv6相关)的主要内容,如果未能解决你的问题,请参考以下文章

Windows下socket编程(console非MFC)

windows下socket编程小例子

在windows下,如何用纯C语言实现socket网络编程?

Windows Socket域名解析

WinSock1.1和WinSock2.0

Windows Socket和Linux Socket编程有什么区别