如何删除多余的循环?

时间:2019-09-11 06:51:04

标签: c

我需要使代码更具可读性,但是周期很多,我能以某种方式解决此问题吗?

变量i不断跳来跳去,调试时非常不方便。

for(;;)
{
    //
    // For connection orientated protocols, we will handle the
    // packets received from a connection collectively.  For datagram
    // protocols, we have to handle each datagram individually.
    //

    //
    // Check to see if we have any sockets remaining to be served
    // from previous time through this loop.  If not, call select()
    // to wait for a connection request or a datagram to arrive.
    //

    for (i = 0; i < numSocket; i++)
    {
        if (FD_ISSET(servSock[i], &SockSet))
            break;
    }

    if (i == numSocket)
    {
        for (i = 0; i < numSocket; i++)
        {
            FD_SET(servSock[i], &SockSet);
        }

        if (select(numSocket, &SockSet, 0, 0, 0) == SOCKET_ERROR)
            continue;
    }

    for (i = 0; i < numSocket; i++)
    {
        if (FD_ISSET(servSock[i], &SockSet))
        {
            FD_CLR(servSock[i], &SockSet);
            break;
        }
    }

...

}

2 个答案:

答案 0 :(得分:3)

要使代码更具可读性(可测试和可维护),您可以将某些逻辑封装到具有有意义名称的单独函数中。考虑这个版本的循环

for(;;)
{
    int i = find_socket_to_be_served(numSocket, servSock, &SockSet);

    if (i == numSocket)
    {
        set_all_sockets(numSocket, servSock, &SockSet);

        if (select(numSocket, &SockSet, 0, 0, 0) == SOCKET_ERROR)
            continue;
    }
    // ...
}

其中使用的两个函数定义为

int find_socket_to_be_served(int n_sockets, int *fds, fd_set *fdset)
{
    int i = 0;
    for (; i < n_sockets; i++)
    {
        if (FD_ISSET(fds[i], fdset))
        {
            FD_CLR(fds[i], fdset);
            break;
        }
    }
    return i;
}

void set_all_sockets(int n_sockets, int *fds, fd_set *fdset)
{
    for (int i = 0; i < n_sockets; i++)
    {
        FD_SET(fds[i], fdset);
    }  
}

答案 1 :(得分:1)

据我了解您的代码,您不需要FD_CLEAR()一个一个地插入套接字。
只需一次FD_ZERO()所有它们,然后使用单个循环再次FD_SET()
请注意,在select()之后,可以准备使用许多套接字。使用完后,您不必break
另请注意,select()的第一个参数在Windows上未使用,但应该随处都为套接字文件描述符的 1 + max (而不是它们的数量)其他。

for(;;)
{
    FD_ZERO(&SockSet);
    for (int i = 0; i < numSocket; i++)
    {
        FD_SET(servSock[i], &SockSet);
    }
    if (select(numSocket, &SockSet, 0, 0, 0) == SOCKET_ERROR)
        continue; // or probably break...
    }
    for (int i = 0; i < numSocket; i++)
    {
        if (FD_ISSET(servSock[i], &SockSet))
        {
            // use servSock[i]
        }
    }
}