strcmp не работает на итеративном сервере C - PullRequest
0 голосов
/ 09 мая 2018

Мы работаем на итеративном сервере в C, который можно использовать с клиентом telnet в UNIX. Наш код работает нормально, за исключением случаев, когда выполняется сравнение строк с использованием strcmp (). Мы пробовали исправить это, используя \ n как предложено на этом форуме. Код ниже работает отлично. Мы даже вводим метод checkInput(in,out)

while(read(fileDescriptor,in,2000)>0)
{
    in[strlen(in)-1]=0;
    checkInput(in,out);
    write(fileDescriptor,out,strlen(out));
}

Когда мы вводим checkInput(in,out), мы хотим заключить строку, которую пользователь вводит через telnet, с другой предопределенной строкой. Но мы всегда заканчиваем оператором else, хотя строки twor одинаковы.

void checkInput(char in[],char out[])
{
    char tempString[]="GET TEMPERATURE\n";
    char buzzer[]="GET BUZZER";

    if(strcmp(in,tempString)==0)
    {
        strcpy(out,"Get Temp!");
        //sprintf(out,"%d",temp);
    }

    else if(strcmp(in,"GET HUMIDITY")==0)
    {
        strcpy(out,"Get Hum!");
        //sprintf(out,"%d",hum);
    }

    else if(strcmp(in,"GET LIGHT")==0)
    {
        strcpy(out,"Get Light!");
        //sprintf(out,"%d",light);
    }

    else if(strcmp(in,"GET LED")==0)
    {
        strcpy(out,"Get LED!");
        //sprintf(out,"%d",led);
    }

    else if(strcmp(in,"GET SOUND")==0)
    {
        strcpy(out,"Get Sound!");
        //sprintf(out,"%d",sound);
    }

    else if(strncmp(in,buzzer, 11)==0)
    {
        strcpy(out,"Get Buzzer!");
        //sprintf(out,"%d",buzzer);
    }

    else if(strcmp(in,"exit")==0)
    {
        strcpy(out,"Exiting... Get Out!");
        exit(2);
    }
    else
    {
        strcpy(out,"\nDAAAAAMN YOU SERVER!!!!!!!!!\n");
        sprintf(out,"%d",strcmp(in,buzzer));
    }
}

Любая помощь будет принята с благодарностью! Спасибо!

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

следующий предложенный фрагмент кода должен решить вашу проблему

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


// prototypes
void checkInput(char in[],char out[]);
void readWriteLoop( void );

void readWriteLoop();
{
    char in[2000];
    char out[2000];

    FILE * fp = NULL;

    fp = fopen( ..., "a+" ); // replace .... with the actual I/O device name
    if( !fp )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    while( fgets( in, sizeof( in ), fp) )  
    { 
        in[ strspn( in, "\n" ) ] = '\0'; 
        checkInput( in, out );
        fprintf( fp, "%s\n", out );
    }

    fclose( fp );
}
0 голосов
/ 09 мая 2018

Давайте попробуем небольшой эксперимент.

В одном сеансе мы запускаем netcat (nc процесс), который прослушивает соединение и сбрасывает то, что оно получает, через hexdump (hd), чтобы мы могли видеть, что на самом деле отправляет telnet:

$ nc -l 8888|hd

В другом сеансе мы используем telnet для отправки небольшой строки:

$ telnet localhost 8888 <<<"Hello, world!"

Теперь, что мы видим в первом терминале?

$ nc -l 8888|hd
00000000  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 21 <b>0d</b> 0a     |Hello, world!..|
0000000f
$

Telnet отправляет CRLF в конце каждой строки (при условии, что линия была изначально завершена с помощью LF). Поэтому, когда вы разделяете полученный ввод на строки на стороне сервера, вам необходимо удалить как \r, так и \n. (Если по какой-либо причине исходная строка была прервана на \r вместо \n, то, что вы получите на другом конце, обычно будет строкой, оканчивающейся на \r\0, хотя telnet имеет возможность отправить \r\n и в этом случае.

Обратите внимание, что вы не должны предполагать, что один вызов read вернет всю строку или что она вернет только одну строку. Объем данных, который создается одним вызовом read, подвержен столь многочисленным изменениям окружающей среды, что никаких предположений не следует делать. Как минимум, вы должны найти конец строки, отсканировав \r, а затем отбросив как \r, так и следующие \n или \0. Если терминатор строки не найден, нужно будет прочитать больше данных. Если за разделителем строки следуют дополнительные данные, то их нужно будет обработать на следующем шаге, вместо того, чтобы (или до) читать больше ввода из сокета.

Для получения дополнительной информации по этому вопросу см. RFC-1123"Требования к хостам в Интернете" (который определяет протокол telnet в главе 3) и, в частности, раздел 3.3.1 "Конец Telnet. конвенция ".

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