UDP服务器消耗多线程程序中的所有处理器时间

时间:2017-09-12 06:02:15

标签: c++ multithreading sockets select udp

我正在开发一个客户端/服务器应用程序。客户端和服务器在运行Ubuntu 16.04的两台不同计算机上运行。客户端发送两个影响服务器部分流量的变量,因此,我希望尽可能地降低丢包率。我的应用程序是基于线程的。

在一个线程中UDP服务器正在运行。我的项目有一个使用Qt实现的GUI。当我尝试实现UDP服务器阻塞时,整个程序和GUI冻结,直到收到数据包。有时即使收到数据包,程序也没有响应。

因此,我认为非阻塞UDP是最好的方法。我设法使用select()使UDP无阻塞。现在出现了问题。如果我将recvfrom的超时设置为10毫秒并允许线程每10毫秒运行一次,几乎没有数据包丢失,但显然,UDP线程消耗程序冻结的所有处理器时间。如果我增加了调用线程的间隔或减少了超时间隔,则大约80%的数据包会丢失。我知道UDP是无连接协议,TCP可能是更好的选择,但我必须使用UDP,因为客户端通过UDP发送数据包。

问题是:如何在不阻止其他线程高效执行的情况下降低丢包率?

以下是我的代码(基于Stackoverflow的答案,目前我找不到这里的引用)。

void receiveUDP(void)
{
    fd_set readfds;
    static int fd;
    static struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 10000;
    static char buffer[10];
    static int length;

    if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
        perror("socket failed");
        return;
    }

    struct sockaddr_in serveraddr;
    memset( &serveraddr, 0, sizeof(serveraddr) );
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons( 50037 );    
    serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );     
    if( bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
    {
        perror("bind failed");
        return;
    }

    fcntl(fd, F_SETFL, O_NONBLOCK);

    FD_ZERO(&readfds);
    FD_SET(fd, &readfds);

    int rv = select(fd+1, &readfds, NULL, NULL, &tv);

    if(rv == -1)
    {
        printf("Error in Select\n");
        _exit(0);
    }
    else if(rv == 0)
    {
        printf("Timeout\n");
    }
    else
    {
        if(FD_ISSET(fd, &readfds))
        {
            length = recvfrom(fd, buffer, sizeof(buffer) - 1, 0, NULL, 0);

            if(length < 0)
            {
                perror("recvfrom failed");
            }
            else
            {
                printf("%d bytes received: \n", length);
            }
        }
    }

    close(fd);
}

0 个答案:

没有答案