【问题标题】:Poll hangs in c民意调查挂在c
【发布时间】:2021-11-15 03:24:21
【问题描述】:
#define RETRY_TIMEOUT 2

while(1)
{
    read_size = SocketReceive(hSocket, recvBuf, sizeof(recvBuf),
                              rsHndl, RETRY_TIMEOUT);
}

int SocketReceive(int hSocket,uint8_t* Rsp,short RvcSize, EMHANDLE *rsHndl,
                                      unsigned short timeout)
{                                     
    struct pollfd fds[1];
    int rv = -1;

    fds[0].fd = hSocket;
    fds[0].events = POLLIN;

    if ((rv = poll(fds, 1, timeout * 1000) > 0))
    {
        if (fds[0].revents & POLLIN)
        {
            shortRetval = recv(hSocket, Rsp, RvcSize, 0);
        }
    }
}

这是客户端代码。当我用我的服务器(能够处理 250 个客户端)测试 10 个客户端时,这段代码运行良好,没有任何问题。当我尝试使用 250 个客户端时,轮询在客户端挂起。这是代码的简化版

【问题讨论】:

  • 请不要提供简化版本,除非它可以清楚地用于重现问题。这里的一个简单解释是那里没有数据,因此 poll 不会报告任何要读取的数据。这意味着人们不仅需要此代码片段,还需要发生问题的实际代码以及有关如何运行代码以使问题发生的足够信息。见How to create a Minimal, Reproducible Example
  • 您有任何理由认为问题出在客户端吗?听起来这很可能是您的服务器出了问题,而且您还没有向我们展示任何服务器代码。

标签: sockets server tcp client


【解决方案1】:

此声明:

if ((rv = poll(fds, 1, timeout * 1000) > 0))

需要改为:

if ((rv = poll(fds, 1, timeout * 1000)) > 0)

注意倒数第二个右括号的位置。 > 的优先级高于 =,所以解析原始语句就好像它是这样写的,这不是你想要的:

if ((rv = (poll(fds, 1, timeout * 1000) > 0)))

此外,SocketReceive() 被声明为返回 int,但您的实现中没有 return 语句。

话虽如此,请尝试更多类似的东西:

while(1)
{
    read_size = SocketReceive(hSocket, recvBuf, sizeof(recvBuf),
                              rsHndl, RETRY_TIMEOUT);
    if (read_size > 0)
    {
        // bytes received...
    }
    else if (read_size == 0)
    {
        // peer disconnected...
    }
    else if (errno == ETIMEDOUT)
    {
        // read timed out...
    }
    else
    {
        // error ...
    }
}

int SocketReceive(int hSocket, uint8_t* Rsp, short RvcSize, EMHANDLE *rsHndl,
                                      unsigned short timeout)
{                                     
    struct pollfd fds;
    fds.fd = hSocket;
    fds.events = POLLIN;

    int rv = poll(&fds, 1, timeout * 1000)
    if (rv > 0)
    {
        return recv(hSocket, Rsp, RvcSize, 0);
    }
    else if (rv == 0)
    {
        errno = ETIMEDOUT;
    }

    return -1;
}

【讨论】:

  • 我已按照您的代码进行了更改。但民意调查仍然有 250 个客户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 2020-12-27
  • 2017-05-06
  • 1970-01-01
相关资源
最近更新 更多