【问题标题】:poll() with non blocking udp socket使用非阻塞 udp 套接字的 poll()
【发布时间】:2012-06-07 19:54:18
【问题描述】:

我正在尝试制作一个由其他人编写的 c++ 程序。我很难理解它。我什至不确定我们是否可以将 poll() 与 UDP 套接字一起使用,但我正在重构的代码是使用 poll() 从 udp 套接字读取如下:

fd.fd = m_bsocket;
fd.events = POLLIN;


iPollResult = poll(&fd, 1, iTimeout);

if(iPollResult > 0)
{
    int iReceivedByteCount = recv(m_bsocket, p_pBuffer, p_iBufferSize, 0);
    if(iReceivedByteCount > 0)
    {
        *p_pReadSize = iReceivedByteCount;
    }
    else
    {
        eReturnValue = UDP_READ_ERROR;
    }
}

return eReturnValue;

我尝试使用命令行向该程序发送 udp 数据包:

回显“123”| nc -u 127.0.0.1 25

看起来 poll() 总是超时并返回 0,因此我无法读取任何内容。

我还写了一个小c#程序,发送udp数据报,但是收不到消息。我想知道我做错了什么......

【问题讨论】:

  • 抱歉没有包括,1000 毫秒。我也尝试将其设置为 10000 毫秒,但没有帮助。也许我以错误的方式创建套接字。
  • 如果是unix,看看netstat和tcpdump能否给出更多信息。 Windows 也有类似的工具。
  • 当我运行 netstat -lu 时,我没有看到任何在我的端口 25 上侦听的内容,是因为我正在使用 poll() 还是其他可能被搞砸了?
  • 套接字是连接的(即使用acceptconnect 创建的)还是未连接的?虽然这无关紧要,因为 UDP 套接字应该是“可轮询的”,无论它是连接还是未连接。
  • 您不需要connect()(UDP 是无连接的)您需要bind() 到您正在侦听的接口的IP 的套接字或0.0.0.0 对于所有接口。发送到目的地时,使用sendto()

标签: c++ sockets udp


【解决方案1】:

虽然 UDP 套接字可用于连接到另一台主机,但它们大多用于“无连接”。阅读您的问题和 cmets,您有一个连接的套接字是没有意义的。相反,它应该是无连接的,正如 WouterH 在他的评论中所建议的那样。

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

struct sockaddr_in sin = { 0 };
sin.sin_family = AF_INET;
sin.sin_port = htons(25);
sin.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr *) &sin, sizeof(sin));

// Make socket non-blocking if needed

使用上面的代码,每当有人向您主机的任何地址的端口 25 发送 UDP 数据包时,您的套接字都会拦截它。使用例如pollselect 了解数据何时可用。

【讨论】:

  • 我完全同意,这解决了我的问题,我想如果我从头开始编写我的 udpcommunication 类会容易得多:)
【解决方案2】:

您无需致电connect(),因为 UDP 是无连接的。您需要将套接字 bind() 连接到您正在侦听的接口的 IP 或所有接口的 0.0.0.0 (INADDR_ANY)。发送到目的地时,请使用sendto()

为了完整起见:如果您在 UDP 套接字上调用 connect(),您只是为 send() 函数设置了默认目标(然后您可以使用 send 而不是 sendto)。

如果你想接收数据,你总是要bind()这个socket到接口,或者所有接口。请注意,您必须从收到的消息中验证源地址。因此,您可能希望通过使用recvfrom() 并检查源地址来过滤发件人。

【讨论】:

  • 在 UDP 套接字上调用 connect 不仅仅是设置默认目标。例如,它会导致来自任何其他来源的所有入站数据报被丢弃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多