我的handle_clients函数有什么问题

时间:2017-05-09 00:24:09

标签: c sockets networking telnet

套接字编程相当新,所以这就是我的问题。怎么了?我的功能是从telnet会话中获取输入,然后当您按下“输入”时它应该打破while循环。但它并不是出于某种原因。我无法弄清楚为什么,我已经尝试了各种各样的方法,但到目前为止我还没有尝试过。

void handle_clients(socket,address)
    int *socket;
    const char *address;
{
    char msg[256];
    char cmd[128];
    int bytes;

    memset(msg,0,sizeof(msg));
    memset(cmd,0,sizeof(cmd));
    while(1) {
        send(*socket,"CMD >> ",7,0);
        bytes = 0;
        while((bytes = recv(*socket,cmd,sizeof(cmd),0)) > 0) {
            if(bytes < 0) {
                sprintf(msg,"Error: receiving from %s.\r\n",
                    address);
                send(*socket,msg,strlen(msg),0);
                break;
            }
            if(cmd[bytes] == 10 || cmd[bytes] == 13) {
                break;
            }
        }

        if(strcmp(cmd,"exit") == 0) {
            break;
        } else if(strcmp(cmd,"help") == 0) {
            sprintf(msg,"Commands: [exit,cmd,help]\r\n");
            send(*socket,msg,strlen(msg),0);
        } else if(strcmp(cmd,"cmd") == 0) {
            memset(cmd,0,sizeof(cmd));
            send(*socket,"Enter command: ",15,0);
            bytes = 0;
            while((bytes = recv(*socket,cmd,sizeof(cmd),0)) > 0) {
                if(bytes < 0) {
                    sprintf(msg,"Error: receiving from %s.\r\n",
                        address);
                    send(*socket,msg,strlen(msg),0);
                    break;
                }
                if(cmd[bytes] == 10 || cmd[bytes] == 13) {
                    break;
                }
            }
            system(cmd);
        } else {
            sprintf(msg,"Unknown command.\r\n");
            send(*socket,msg,strlen(msg),0);
        }
        memset(msg,0,sizeof(msg));
        memset(cmd,0,sizeof(cmd));
    }
}

void handle_clients(socket,address) int *socket; const char *address; { char msg[256]; char cmd[128]; int bytes; memset(msg,0,sizeof(msg)); memset(cmd,0,sizeof(cmd)); while(1) { send(*socket,"CMD >> ",7,0); bytes = 0; while((bytes = recv(*socket,cmd,sizeof(cmd),0)) > 0) { if(bytes < 0) { sprintf(msg,"Error: receiving from %s.\r\n", address); send(*socket,msg,strlen(msg),0); break; } if(cmd[bytes] == 10 || cmd[bytes] == 13) { break; } } if(strcmp(cmd,"exit") == 0) { break; } else if(strcmp(cmd,"help") == 0) { sprintf(msg,"Commands: [exit,cmd,help]\r\n"); send(*socket,msg,strlen(msg),0); } else if(strcmp(cmd,"cmd") == 0) { memset(cmd,0,sizeof(cmd)); send(*socket,"Enter command: ",15,0); bytes = 0; while((bytes = recv(*socket,cmd,sizeof(cmd),0)) > 0) { if(bytes < 0) { sprintf(msg,"Error: receiving from %s.\r\n", address); send(*socket,msg,strlen(msg),0); break; } if(cmd[bytes] == 10 || cmd[bytes] == 13) { break; } } system(cmd); } else { sprintf(msg,"Unknown command.\r\n"); send(*socket,msg,strlen(msg),0); } memset(msg,0,sizeof(msg)); memset(cmd,0,sizeof(cmd)); } }

2 个答案:

答案 0 :(得分:0)

这有一个逻辑问题:

 while((bytes = recv(*socket,cmd,sizeof(cmd),0)) > 0) {
        if(bytes < 0) {

        }
 }

字节将始终大于零,因此if(bytes&lt; 0){}块永远不会 执行。

您可能想将其更改为

 while((bytes = recv(*socket,cmd,sizeof(cmd),0))) {
        if(bytes < 0) {

        }
 }

如果bytes等于零,则循环时不会进入。

答案 1 :(得分:0)

  

应该打破while循环。但它并不是出于某种原因。

除了我的同行指出的问题之外,我认为您的具体调查的答案在于嵌套的while循环以及\r\n中缺少的strcmp字符。 / p>

由于while循环是嵌套的,因此break可能会在容器循环仍然存在的情况下破坏嵌套循环 - 因此您将在下一次迭代中返回下一个嵌套循环。

例如:

while(1) {
    send(*socket,"CMD >> ",7,0);
    bytes = 0;
    while((bytes = recv(*socket,cmd,sizeof(cmd),0))) {
        if(bytes < 0) {
            sprintf(msg,"Error: receiving from %s.\r\n",
                address);
            send(*socket,msg,strlen(msg),0);
            break; /* <= WHICH LOOP ARE WE BREAKING? */
        }
        if(cmd[bytes] == 10 || cmd[bytes] == 13) {
            break; /* <= WHICH LOOP ARE WE BREAKING? */
        }
    }
    // ...
 }

这是goto可能是你的朋友......

的案例之一

...虽然我认为在你去那里之前代码可能需要更好更优雅的解决方案和更改。

此外,如果您要覆盖现有缓冲区,重新读取数据的重点是什么?

我几乎(在这种情况下)发现它更方便,并且可能忽略不完整的TCP / IP数据包/命令的可能情况。

在这种特殊情况下,似乎可以假设如果命令没有以新行结束,则出现问题,我们可以断开连接。这种短命令应该传入单个TCP / IP数据包。即:

while(1) {
    send(*socket,"CMD >> ",7,0);
    bytes = 0;
    bytes = recv(*socket,cmd,sizeof(cmd),0);
    if(!bytes) { // closed by peer
       close(*socket);
       return;
    }
    if(bytes < 0 || cmd[bytes-1] == 10 || cmd[bytes-1] == 13) {
       if(errno == EINTR)
         continue;
       sprintf(msg,"Error: receiving from %s.\r\n",
                   address);
       close(*socket);
       return;
    }
    if(strcmp(cmd,"exit\r\n") == 0) {
        break;
    } else if(strcmp(cmd,"help\r\n") == 0) {}
    // ...
 }

这段代码显然忽略了在单个recv中读取多个命令的可能性(即缓冲区为"help\r\ncmd\r\nX\r\nexit\r\n")......但是你可以在某个时候解决这个问题。 / p>