C - Как избежать чтения лишних символов из стандартного ввода во время ожидания потока? - PullRequest
0 голосов
/ 01 марта 2020

Я пишу клиент-серверную игру на C (я могу использовать только стандартные библиотеки). Приложение сервера создает поток для каждого подключенного клиента, чтобы управлять им. Клиенту нужно подождать определенное время, чтобы получить некоторые данные из потока, который его обрабатывает, затем он отправляет данные. Проблема заключается в том, что пользователь может записывать в терминал, когда он ожидает данных, поэтому scanf (или аналогичный) читает эти данные в буфере и отправляет их на сервер в виде команд.

void game(int server_sd){
    char msg;
    char buffer[200];
    char buf[500];
    char row[16];
    int rows;
    int cols;
    int stdin_copy;
    read(server_sd, &playerLetter, 1); //Client waits for data. Here we can write into terminal and buffer into stdin
    while(1){
        system("clear");
        printMap(server_sd);        //Prints the map
        receiveMessage(server_sd);  //Receives a message from server
        clearBuffer();
        scanf("%s",buffer);  //This scanf reads the buffered stdin
        msg = firstChar(buffer);
        write(server_sd, &msg, 1); //...And then the client sends these dirty commands to server
        if(gameFinished){
            printf("Starting new game...\n");
            if(read(server_sd, &playerLetter, 1)<=0){  //Client waits for data. Here we can write into terminal and buffer into stdin
                break;
            }
            gameFinished = 0;
        }       
    }
}


void clearBuffer(){
    char c;
    while ((c = getchar()) != '\n' && c != EOF) { };
}

Например: нет активных клиентов. Клиент А - первый игрок. Сервер спит 10 секунд перед началом новой игры. Например, в течение этого периода я могу написать (новые строки, когда я нажимаю клавишу ввода):

q
d
s

Эти буквы помещаются в буфер stdin, поэтому scanf автоматически читает их. Клиент отправляет их на сервер с записью (server_sd, & msg, 1).

clearBuffer очищает символы до первого \ n. Я не смог найти способ очистить весь буфер stdin.

Заранее спасибо.

РЕДАКТИРОВАТЬ

Я пытался select

int checkSTDIN(){
    fd_set rd;
    struct timeval tv={0};
    int ret;

    FD_ZERO(&rd);
    FD_SET(STDIN_FILENO, &rd);
    ret=select(1, &rd, NULL, NULL, &tv);
    return (ret>0);
}
.
.
.
read(server_sd, &playerLetter, 1); //Client waits for data. Here we can write into terminal and buffer into stdin

while(checkSTDIN())
   getchar();
.
.
.

Но это не сработало

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...