为什么 AF_INET 不能与 SOCK_STREAM 一起工作?

Why isn't AF_INET working with SOCK_STREAM?

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

#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;
}

我的 return 为 3,WSA 错误代码为 10047

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

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

我认为一个问题(可能不是唯一的问题,但这是我突然想到的问题)在这一行中:

inet_pton(AF_INET,stringaddr,&tobind);

问题是您将 &tobind 作为最后一个参数传递,而 tobind 是一个 sockaddr,但 inet_pton() 期望它的第三个参数指向一个struct in_addr 而不是在使用 AF_INET 时(inet_pton() 的第三个参数采用 void-pointer 而不是类型指针这一事实使得这种错误很容易犯)。 =23=]

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

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;
[...]