为什么AF_INET不能使用SOCK_STREAM?

时间:2016-01-10 06:11:15

标签: c++ sockets networking winsock2

我刚刚开始更好地理解套接字编程,并且我正在尝试构建一个可以发送和接收消息的简单程序。我遇到了将套接字绑定到地址以使用它的问题。这就是我所拥有的 -

#include "stdafx.h"

using namespace std;

int main()
{
    bool devbuild = true;

    WSADATA mainSdata;
    SOCKET sock = INVALID_SOCKET;
    sockaddr tobind;
    tobind.sa_family = AF_INET;
    char stringaddr[] = "192.168.1.1";
    inet_pton(AF_INET,stringaddr,&tobind);


    //initiating Windows Socket API (WSA)
    if (WSAStartup(2.2, &mainSdata) == 0)
    {
        if (devbuild == true)
        {
            printf("WSA successfully started...\n");
        }
    }
    else
    {
        printf("WSA failed to set up, press [ENTER] to exit...\n");
        pause();
        return 1;
    }

    //instantiating the socket
    sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, NULL);
    if (sock != INVALID_SOCKET)
    {
        if (devbuild == true)
        {
            printf("Socket successfully created...\n");
        }
    }
    else
    {
        printf("Socket failed to set up, press [ENTER] to exit...\n");
        pause();
        return 2;
    }

    //binding the socket
    if (bind(sock, &tobind, sizeof(tobind)) == 0)
    {
        if (devbuild == true)
        {
            printf("Socket successfully bound...\n");
        }
    }
    else
    {
        printf("Socket failed to bind, press [ENTER] to exit...\n");
        printf("Last WSA error was: %d", WSAGetLastError());
        pause();
        return 3;
    }


    pause();


    return 0;
}

我收到3,WSA错误代码 10047

10047 - WSAEAFNOSUPPORT 协议族不支持的地址族。 使用了与所请求的协议不兼容的地址。所有套接字都使用关联的地址系列(即Internet协议的AF_INET)和通用协议类型(即SOCK_STREAM)创建。如果在套接字调用中显式请求了错误的协议,或者如果将错误的系列的地址用于套接字(例如,在sendto中),则会返回此错误。

这没有意义,因为我只使用相互支持的SOCK_STREAM和AF_INET。

1 个答案:

答案 0 :(得分:3)

我相信一个问题(可能不是唯一的问题,但这就是跳出来的问题)就在这一行:

inet_pton(AF_INET,stringaddr,&tobind);

问题是您传递的是&tobind作为最终参数,而tobindsockaddr,但inet_pton()期望其第三个参数指向struct in_addr相反,当使用AF_INET时(inet_pton()采用空指针而不是第三个参数的类型指针这一事实使得这种错误变得非常容易)。

所以你应该做的是(注意还添加错误检查):

if (inet_pton(AF_INET,stringaddr,&tobind.sin_addr) != 1)
   printf("inet_pton() failed!\n");

此外,您需要使tobind类型为struct sockaddr_in,而不仅仅是sockaddr,并且您还需要在使用之前将结构清零:

struct sockaddr_in tobind;
memset(&tobind, 0, sizeof(tobind));   // make sure the uninitialized fields are all zero
tobind.sa_family = AF_INET;
[...]