【问题标题】:Can not bind socket to address无法将套接字绑定到地址
【发布时间】:2019-12-10 23:17:25
【问题描述】:

我正在尝试编写一些客户端代码以将 UDP 数据包发送到具有特定 IP 地址的另一台计算机。当 IP 地址设置为 home 时,它​​工作得很好。我可以使用wireshark 来查看正在发送的数据包。当我输入服务器的 IP 时,我没有看到任何数据包。经过进一步调查,我发现当我尝试绑定到套接字时出现 10049 错误。我不太明白为什么我不能绑定到网络上另一台计算机的 IP。

    string m_port = "2033";             //  port that the plugin is talking to
    string m_hostIP = "192.168.2.27";           //  IP address that the plugin is talking to

    //  start Windows Sockets
    if ((error = WSAStartup(version, &data)) != NO_ERROR)
    {
        logError("Error: WSAStartup failed with error: ", error);
        return;
    }
    // check if version 2.2 of Winsock is supported
    if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)
    {
        logError("Error: System could not support WinSock 2.2.", 0);
        // clean up Winsock
        if (WSACleanup() == SOCKET_ERROR)
        {
            logError("Error: Winsock cleanup error: ", WSAGetLastError());
        }
        return;
    }

    //  create a datagram socket using IPv4 and UDP protocol
    if ((m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
    {
        logError("Error: Socket creation failed with error: ", WSAGetLastError());
        //  clean up Winsock
        if (WSACleanup() == SOCKET_ERROR)
        {
            logError("Error: Winsock cleanup error: ", WSAGetLastError());
        }
        return;
    }

    int iSetOption = 1;
    if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&iSetOption, sizeof(iSetOption)) == SOCKET_ERROR)
    {
        logError("Error: Set Socket Options failed with error: ", WSAGetLastError());

        //  close the socket
        if (closesocket(m_socket) == SOCKET_ERROR)
        {
            logError("Error: Unable to close socket: ", WSAGetLastError());
        }
        //  clean up Winsock
        if (WSACleanup() == SOCKET_ERROR)
        {
            logError("Error: Winsock cleanup error: ", WSAGetLastError());
        }

        m_socket = INVALID_SOCKET;
        return;
    }

    struct sockaddr_in server_addr;             //  server address description struct
    int server_addr_len = sizeof(server_addr);  //  size of server address struct
    int bytesSent = 0;

    memset((char *)&server_addr, 0, server_addr_len);           //  clear the address struct
    server_addr.sin_family = AF_INET;                           //  IPv4 address type
    server_addr.sin_port = htons((unsigned short)stoul(m_port));    //  port used by the simulator to send the data
    server_addr.sin_addr.s_addr = inet_addr(m_hostIP.c_str());          //  any server IP address will do

    //  bind the socket to the address struct
    if (::bind(m_socket, (struct sockaddr *) &server_addr, server_addr_len) == SOCKET_ERROR)
    {
        logError("Error: unable to bind the socket: ", WSAGetLastError());
        //  close the socket
        if (closesocket(m_socket) == SOCKET_ERROR)
        {
            logError("Error: Unable to close socket: ", WSAGetLastError());
        }
        // clean up Winsock
        if (WSACleanup() == SOCKET_ERROR)
        {
            logError("Error: Winsock cleanup error: ", WSAGetLastError());
        }

        m_socket = INVALID_SOCKET;
        return;
    }

【问题讨论】:

  • 您将套接字绑定到本地地址。您将其连接或发送到远程地址。您根本不需要绑定客户端套接字。只需将其删除。
  • "some client code" - 这应该告诉您您使用了错误的功能。 bind 通常用于将套接字绑定到本地主机地址。 connect 用于将套接字连接到远程地址。对于 UDP,您可能想使用 sendto 无论如何。
  • 为什么将端口定义为字符串而不是整数是另一个谜。

标签: c++ sockets winsock2 udpclient


【解决方案1】:

您绑定套接字以选择从哪个本地端点(地址+端口)发送数据。

服务器可能有多个网卡将您连接到互联网,或者您可能有多个网络 - 通过绑定,您可以选择发送数据的网卡(或任何实际的网卡)。

PC 通常只有几个可用地址(本地主机和网络地址),但您也可以指定端口。端口可用于过滤不需要的数据包,这在您想要创建多个套接字时会很有帮助。

另一个操作称为connect - 选择将数据发送到哪个远程端点。我不记得它在 winsocket/udp 上是如何工作的确切细节。这可能是不必要的,您只需发送数据并指定每次发送的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 2020-02-20
    • 2014-05-10
    • 2011-11-25
    • 1970-01-01
    • 2012-06-15
    • 2015-07-03
    相关资源
    最近更新 更多