【问题标题】:How can I stop the while?我怎样才能停止这段时间?
【发布时间】:2020-06-20 16:13:23
【问题描述】:

我有一个 TCP 服务器客户端,我在其中输入了一个数字,其中包含我想将单词发送到服务器的次数。所以我发送正确,因为我在一个循环(在客户端)上打印信息,但在服务器中无限显示,因为我放了 while(1) 但如果我不使用,只打印一次。我不想将号码发送到服务器。

如果我输入数字 4,我想将单词“hello”打印四次 这是服务器,现在它显然正在无限打印。

#define MAXPENDING 5    /* Maximum number of simultaneous connections */
#define BUFFSIZE 255    /* Size of message to be received */

void err_sys(char *mess) { perror(mess); exit(1); }

void handle_client(int sock) {
    char buffer[BUFFSIZE];
    int received = -1;
    while (1) {
        /* Read from socket */
        read(sock, &buffer[0], BUFFSIZE);
        printf("Message from client: %s\n", buffer);

        /* Write to socket */
        write(sock, buffer, strlen(buffer) + 1);

        /* Close socket */
        close(sock);
    }
}
int main(int argc, char *argv[]) {
    struct sockaddr_in echoserver, echoclient;
    int serversock, clientsock;
    int result;

    /* Check input arguments */
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        exit(1);
    }

    /* Create TCP socket */
    serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (serversock < 0) {
        err_sys("Error socket");
    }

    /* Set information for sockaddr_in structure */
    memset(&echoserver, 0, sizeof(echoserver));       /* we reset memory */
    echoserver.sin_family = AF_INET;                  /* Internet/IP */
    echoserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* ANY address */
    echoserver.sin_port = htons(atoi(argv[1]));       /* server port */

    /* Bind socket */
    result = bind(serversock, (struct sockaddr *) &echoserver, sizeof(echoserver));
    if (result < 0) {
        err_sys("Error bind");
    }

    /* Listen socket */
    result = listen(serversock, MAXPENDING);
    if (result < 0) {
        err_sys("Error listen");
    }
    while (1) {
        unsigned int clientlen = sizeof(echoclient);

        /* Wait for a connection from a client */
        clientsock = accept(serversock, (struct sockaddr *) &echoclient, &clientlen);
        if (clientsock < 0) {
            err_sys("Error accept");
        }
        fprintf(stdout, "Client: %s\n", inet_ntoa(echoclient.sin_addr));

        /* Call function to handle socket */
        handle_client(clientsock);
    }
}

这是客户

  printf("Enter a number between 0 to 9[0 to exit]: ");
fgets(number, 100, stdin);
while(strtol(number,&pEnd,10)!=0){

    while (!((strtol(number,&pEnd,10) <= 9) && (strtol(number,&pEnd,10) >= 0))) {
        printf("[ERROR] The number you entered is out of range\n");
        printf("Enter a number between 0 to 9[0 to exit]: ");
        fgets(number, 100, stdin);
    }
    if(strtol(number,&pEnd,10)!=0){
        printf("Enter a word: ");
        fgets(buffer, 100, stdin);
        for(int i=0;i<strtol(number,&pEnd,10);i++){
            write(sock, buffer, strlen(buffer) + 1);
            fprintf(stdout, " sent \n");

            read(sock, buffer, BUFFSIZE);
            fprintf(stdout, " %s ...done \n", buffer);
        }

    }
    printf(" Enter a number between 0 to 9[0 to exit]: ");
    fgets(number, 100, stdin);
}

【问题讨论】:

  • 您可以使用breakwhile 的条件。
  • 是的,我就是这么想的,但是什么条件呢?
  • 您应该传递一个 niters 参数或从您的服务器获取它,然后对其进行迭代:while(n) { /*...*/ n--; }
  • 我更新了客户端代码,可能有错误
  • 您需要将strtol 的结果存储在一个变量中。每次循环迭代时都会转换它。

标签: c linux tcp server


【解决方案1】:

你的代码有多个问题:

  • 您不测试read() 是否成功。如果失败,您应该退出循环。
  • 您在循环体中无条件关闭套接字:下一个 read 将失败并立即返回 -1,您将打印一条虚假消息并以恶心的方式进行迭代。
  • 您调用 strlen()printf() 时使用的缓冲区可能不是空终止的,可能会导致未定义的行为。

这是修改后的版本:

void handle_client(int sock) {
    char buffer[BUFFSIZE];
    int received = -1;
    if (sock < 0)
        return;
    for (;;) {
        /* Read from socket */
        received = read(sock, buffer, sizeof(buffer) - 1);
        if (received <= 0)
            break;
        buffer[received] = '\0';
        printf("Message from client: %s\n", buffer);

        /* Write to socket */
        write(sock, buffer, received);
    }
    /* Close socket */
    close(sock);
}

【讨论】:

  • 现在我看到了问题...谢谢
【解决方案2】:

通常不建议您手上有一个无限循环,但如果您需要这样做,请添加一个 if 语句,例如:

while(1){
if(clientsock < 0){/*statement that is met so that your code stops running the if */
  break;
 }
}

【讨论】:

  • 这是我已经拥有的,但没有休息所以没有用,我在发送单词的地方添加了客户端代码,也许错误在那里