4

我正在尝试使用以下 C++ 代码从 IPv4 字符串地址填充 sockaddr_in 结构:

// WSAStringToAddress
struct sockaddr_in sock;

int addrSize = sizeof( struct sockaddr_in );

memset( &sock, 0, addrSize );

sock.sin_family = AF_INET;

rc = WSAStringToAddress( (LPWSTR) "192.168.0.1", 
                         AF_INET, 
                         NULL, 
                        (LPSOCKADDR) &sock, 
                        &addrSize ); 

if ( rc != 0 )
{
    rc = WSAGetLastError();

    printf( "WSAStringToAddress: error=[%d]\n", rc );
}

它失败,错误代码为 10022,即 WSAEINVAL。在http://msdn.microsoft.com/en-us/library/windows/desktop/ms742214%28v=vs.85%29.aspx上,它指出当 sockaddr_in 的地址系列未设置为 AF_INET 或AF_INET6,我已经清楚地做到了。

我在 Windows Server 2008 R2 SP1 上运行 Visual C++ 2008 Express Edition,但我没有使用较新的地址转换功能,因为我需要从 Windows XP/Windows Server 2000 开始向后兼容。

有谁知道如何解决这个问题/我的代码有什么问题?感谢您提供的任何解决方案:D

编辑:我发现使用 WSAStringToAddressA 允许使用 ASCII char 而不是 tchar

4

3 回答 3

6

WSAStringToAddress()WSAEINVAL当它无法翻译请求的地址时失败。不匹配的家庭值并不是WSAEINVAL发生错误的唯一方式。正如@ChristianStieber 所说,您正在使用类型转换来传递一个 8 位char[]字符串文字,其中需要一个 16 位wchar_t*指针。那是完全错误的。您正在将垃圾传递给WSAStringToAddress(),它正在检测它。

TEXT()将字符串文字传递给值时,您需要使用宏LPTSTR,例如:

rc = WSAStringToAddress( TEXT("192.168.0.1"), ... );

否则,WSAStringToAddress()直接调用 Unicode 版本,并L在字符串字面量前加上前缀,使其变为 awchar_t[]而不是 a char[],例如:

rc = WSAStringToAddressW( L"192.168.0.1", ... );
于 2012-07-27T19:44:24.460 回答
0

我在网上看到的例子将 addrSize 设置为 sizeof(struct sockaddr_storage)。

这个链接有一个例子。

于 2012-07-27T19:34:03.473 回答
0

在我看来,此评论并没有说这是此错误的唯一可能原因。

特别是,这条线让我印象深刻:

(LPWSTR) "192.168.0.1",

您正在获取一个 8 位字符串并将其转换为宽版本。您是否尝试使用 L"192...."?

于 2012-07-27T19:34:46.210 回答