【问题标题】:udp server sending data to specific client until any recvfromudp 服务器将数据发送到特定客户端,直到任何 recvfrom
【发布时间】:2016-10-19 12:49:41
【问题描述】:

我正在编写一个应该实现基于 UDP 协议的库。 我是主机A,远程是主机B。 我需要从主机 A 的 7011 端口向主机 B 的 7011 端口发送消息。然后主机 B 将响应主机 A 的 7011 端口。通信是异步的,所以我需要 udp 来监听传入的消息,有时也我需要从服务器绑定的同一个端口发送消息。

这是我创建和绑定套接字的方式:

udp_server::udp_server(const std::string &localAddress, int localPort)
    : f_port(localPort), f_addr(localAddress) {
    char decimal_port[16];
    snprintf(decimal_port, sizeof(decimal_port), "%d", f_port);
    decimal_port[sizeof(decimal_port) / sizeof(decimal_port[0]) - 1] = '\0';
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_protocol = IPPROTO_UDP;
    int r(getaddrinfo(localAddress.c_str(), decimal_port, &hints, &f_addrinfo));
    if (r != 0 || f_addrinfo == NULL) {
        throw udp_client_server_runtime_error(
            ("invalid address or port for UDP socket: \"" + localAddress + ":" + decimal_port + "\"").c_str());
    }
    f_socket = socket(f_addrinfo->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
    if (f_socket == -1) {
        freeaddrinfo(f_addrinfo);
        throw udp_client_server_runtime_error(
            ("could not create UDP socket for: \"" + localAddress + ":" + decimal_port + "\"").c_str());
    }
    r = bind(f_socket, f_addrinfo->ai_addr, f_addrinfo->ai_addrlen);
    if (r != 0) {
        freeaddrinfo(f_addrinfo);
        close(f_socket);
        throw udp_client_server_runtime_error(
            ("could not bind UDP socket with: \"" + localAddress + ":" + decimal_port + "\"").c_str());
    }
} 

我在这里尝试发送消息:

ssize_t udp_server::sendto(std::string remoteHost, uint16_t port, const char *message, size_t messageLength) {
    struct sockaddr_in remote;
    remote.sin_family = AF_INET;
    remote.sin_port = htons(7011);
    remote.sin_addr.s_addr = ::inet_addr("10.8.0.6");

    socklen_t addrSize;
    addrSize = sizeof(remote);

    memset(remote.sin_zero, '\0', sizeof(remote.sin_zero));
    dout << "messageLength: " << messageLength << std::endl;
    return ::sendto(this->f_socket, message, messageLength, 0, (struct sockaddr *)&remote, addrSize);
}

但是 ::sendto 总是返回 -1。并且 errno 设置为 22,表示参数无效。可能的解决方案是什么?可能整体结构不好。

=== 解决方案 === 我已经将我的服务器绑定到 locahost :( 应该是 0.0.0.0 或 INADDR_ANY。

【问题讨论】:

  • 你怎么打电话给udp_server::udp_serverserver::sendto
  • this-&gt;server = make_unique&lt;udp_server&gt;('localhost', localControlPort); 然后this-&gt;server-&gt;sendto(this-&gt;remoteHost, this-&gt;controlPort, (const char *)(buffer), static_cast&lt;size_t&gt;(length));

标签: c++ c sockets


【解决方案1】:

如果您绑定到localhost 并尝试发送到非本地 IP,则会发生此错误。

如果你希望能够从任何接口发送,你应该绑定到0.0.0.0

此外,在udp_server::sendto 中,您将remote.sin_portremote.sin_addr 设置为硬编码值。您可能想在此处使用remoteHostport 参数。

【讨论】:

  • 正确。在深度调试中,我决定将参数更改为硬编码值。只是为了确定。
猜你喜欢
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 2021-12-07
相关资源
最近更新 更多