Код клиентского сокета C: сервер не выполняет код после «чтения», пока не будет отправлена ​​другая строка - PullRequest
1 голос
/ 01 апреля 2019

Я пишу код для создания соединения между клиентом и сервером.Клиент отправляет строки на сервер, и сервер должен анализировать и печатать строку в зависимости от того, что было отправлено.

Код клиента:

// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080

int main(int argc, char const *argv[]) {
    struct sockaddr_in address;
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    size_t len = 0;
    char *buffer = NULL;
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\n Socket creation error \n");
        return -1;
    }

    memset(&serv_addr, '0', sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Convert IPv4 and IPv6 addresses from text to binary form
    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        printf("\nConnection Failed \n");
        return -1;
    }

    while(1) {
        getline(&buffer, &len, stdin);
        printf("Line sent: %s", buffer);
        send(sock, buffer, strlen(buffer), 0);
    }
}

Код сервера:

/*Required Headers*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include<string.h>

int main()
{

    char str[100];
    int listen_fd, comm_fd;

    struct sockaddr_in servaddr;

    listen_fd = socket(AF_INET, SOCK_STREAM, 0);

    bzero( &servaddr, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    servaddr.sin_port = htons(8080);

    bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));

    listen(listen_fd, 10);

    comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);

    while(1)
    {
        bzero( str, 100);

        read(comm_fd,str,100);

        printf("Received: %s",str);
        if(strncmp(str, "NEW", 3) == 0)
        {
            printf("Client - NEW");
        }
        else if(strncmp(str, "FILE", 4) == 0)
        {
            printf("Client - FILE");
        }
        else if(strncmp(str, "NAME", 4) == 0)
        {
            strtok(str, ": ");
            printf("NAME: %s", str);
        }
        else if(strncmp(str, "DESCRIPTION", 11) == 0)
        {
            strtok(str, ": ");
            printf("DESCRIP: %s", str);
        }
        else if(strncmp(str, "PRINTER", 7) == 0)
        {
            strtok(str, ": ");
            printf("PRINTER: %s", str);
        }

    }
}

Что я ожидаю, так это то, что когда я отправляю «NEW» с клиента на сервер, сервер печатает «Client - NEW».Затем, когда я отправляю «ФАЙЛ», сервер печатает «КЛИЕНТ - ФАЙЛ».Происходит задержка одного отправления.Поэтому, когда я отправляю NEW, сервер печатает «Received: NEW», но не входит в проверку if, чтобы напечатать «CLIENT - NEW».Затем, когда я отправляю «ФАЙЛ», сервер печатает «Клиент - НОВЫЙ получен: ФАЙЛ».

Что я могу здесь делать не так?

1 Ответ

1 голос
/ 01 апреля 2019

Поэтому, когда я отправляю NEW, сервер печатает «Получено: NEW»

Да, вот здесь:

printf("Received: %s",str);

но если быть точным, вы отправляете "NEW \ n", а сервер печатает "Received: NEW \ n". Эта новая строка актуальна, потому что она запускает вывод на терминалах с линейной буферизацией

, но это не входит в проверку if, чтобы напечатать "CLIENT - NEW".

Да, он выполняет условное выражение:

printf("Client - NEW");

но выходные данные буферизуются до следующей распечатки новой строки.

Затем, когда я отправляю «ФАЙЛ», сервер печатает «Клиент - НОВЫЙ получен: ФАЙЛ».

Теперь, после отправки «ФАЙЛА», выполняется:

printf("Received: %s",str);

с str с содержимым "FILE \ n". Это очищает выходной буфер, который в настоящее время содержит «Клиент - NEWReceve: FILE \ n». Кроме того

printf("Client - FILE");

выполняется (но не выводится, только буферизируется), и процесс повторяется.

Таким образом, исправление заключается в добавлении новой строки "\ n" в конце каждой строки формата printf (или в простых случаях используется put).

printf("Received: %s\n",str); // Although "str" will usually contain a newline, but better play it safe

puts("Client - NEW");

Кроме того, если у вас есть линейный протокол, вы должны переключиться на буферизованный вход для вашего сокета:

comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
FILE *sock = fdopen(comm_fd, "r+");

и затем читать строку за строкой

while (1) {
    fgets(str, sizeof(str), sock);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...