【问题标题】:Bind failed with Invalid argument error绑定失败,参数无效错误
【发布时间】:2013-08-26 12:52:24
【问题描述】:

我正在尝试编写一个使用绑定的简单程序。代码在 solaris 上编译,但我得到一个 bind() failed with Invalid Argument 错误。

我尝试了很多次,但都遇到同样的错误,我无法找出错误。

代码如下:

int my_func ()
{
    struct sockaddr_storage name;
    struct addrinfo hints, *res;
    int status;

    char hostnamestr[256];
    gethostname (hostnamestr, 256);

    int iRC;

    memset(&hints, 0, sizeof(hints));

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((status = getaddrinfo(hostnamestr, NULL, &hints, &res) != 0))
    {
        printf("getaddrinfo: %s\n", gai_strerror(status));
        return 1;
    }

    memcpy(&name, res->ai_addr, res->ai_addrlen);
    freeaddrinfo(res);
    monsocket = socket (name.ss_family, SOCK_STREAM, IPPROTO_TCP);
    int iLastError = WSAGetLastError ();

    if (monsocket == -1)
    {
        fprintf (stderr, "cannot open socket for monitors [%s]\n", wsaerror (iLastError));
        return 1;
    }

    sockopts(monsocket);  
    int flags;
    flags = fcntl (monsocket, F_GETFL);
    iLastError = WSAGetLastError ();

    if (flags < 0)
    {
        fprintf (stderr, "cannot get flags for socket [%s]\n", wsaerror (iLastError));
        return 1;
    }

    iRC = fcntl (monsocket, F_SETFL, flags | O_NONBLOCK);
    iLastError = WSAGetLastError ();

    if (iRC == -1)
    {
        fprintf (stderr, "cannot set flags for socket [%s]\n", wsaerror (iLastError));
        return 1;
    }

    int iPort;
    if(name.ss_family == AF_INET)
    {
        ((struct sockaddr_in *) &name)->sin_port = htons (8091);
    }    
    else if(name.ss_family == AF_INET6)
    {
        ((struct sockaddr_in6 *) &name)->sin6_port = htons (8091);
    }

    struct  sockaddr_in* ipv = (struct sockaddr_in *) &name;
    printf("connecting to addr: %s\n", inet_ntoa(ipv->sin_addr));

    iRC = bind (monsocket, (struct sockaddr *) &name, sizeof (name));
    iLastError = WSAGetLastError ();

    if (iRC == -1)
    {
        close(monsocket);
        monsocket=-1;
        fprintf (stderr, "could not bind to port %d\n", iPort);
        printf("Error %s",wsaerror (iLastError));
        return 1;
    }
    else
    {
        fprintf (SCHED_SHOW_MSG, "bound on port %i\n", ntohs (iPort));
    }
    iRC = listen (monsocket, SOMAXCONN);
    iLastError = WSAGetLastError ();

    if (iRC == -1)
    {
        fprintf (stderr, "could not listen to socket [%s]\n", wsaerror (iLastError));
        return 1;
    }

    return 0;
}

【问题讨论】:

  • 同样的错误,但对我来说,问题出在if (bind(s, (struct sockaddr*)&amp;si_here, sizeof(sockaddr) == -1)) die("bind"); 终极愚蠢。你能看出来吗?

标签: sockets bind


【解决方案1】:
bind (monsocket, (struct sockaddr *) &name, sizeof (name))

您的sizeof(name) 产生通用sockaddr_storage 大小的大小。您需要sockaddr_in 或sockaddr_in6 的大小。

无论如何,你最好直接使用来自getaddrinfo的东西:

monsocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(monsocket, res->ai_addr, res->ai_addrlen);

为此,您必须转移您的 freeaddrinfo(res) 呼叫。

【讨论】:

  • 谢谢,sizeof(sockaddr_in 或 sockaddr_in6) 工作正常。如果我使用绑定(monsocket,res->ai_addr,res->ai_addrlen);
  • @Naga 您可以在getaddrinfo(第二个参数)中指定端口。
【解决方案2】:

我遇到了同样的错误。后来发现我为 AF_INET 创建了套接字,并试图使用 IPv6 地址进行绑定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2018-08-18
    • 1970-01-01
    相关资源
    最近更新 更多