Я выполняю упражнение, в котором мне нужно настроить сеть между клиентом и сервером и заставить их «разговаривать». Мне нужно проверить конкретные ответы от клиента, а затем заставить сервер действовать соответствующим образом. Чтобы прочитать данные от клиента, я использую функцию, которая вызывает recv() в цикле до тех пор, пока либо не появится символ '\n', либо не останется байтов для чтения. Когда цикл заканчивается, последний символ в массиве устанавливается равным '\0'. Когда функция выполнена, я ожидаю получить строку с завершающим нулем, которую затем можно использовать для сравнения. Вот функция -
int read_in(int socket, char *buf, int len) {
char *s = buf;
int slen = len;
int c = recv(socket, s, slen, 0);
while((c>0) && (s[c-1]!='\n')) {
s+=c; slen-=c;
c = recv(socket, s, slen, 0);
}
if (c<0) {
return c;
} else if (c==0) {
buf[0] = '\0';
} else {
s[c-1] = '\0';
}
return len-slen;
}
Теперь я жду соединения, объявляю массив с именем «buf» для хранения того, что я прочитал с помощью вышеуказанной функции, а затем сравниваю 2 строки с помощью strcmp().
int connect_d = accept(listener_d, (struct sockaddr *)&client_addr, &address_size);
char buf[255];
read_in(connect_d, buf, sizeof(buf));
if (strcmp("Hello\0", buf) == 0) {
puts("Hello");
} else {
puts("Not Hello");
}
Я считаю, что строка «buf» содержит «Hello\0», и поэтому сравнение должно пройти успешно. Но это не так. Я не могу понять, почему. Однако, если я использую strncmp() для сравнения первых 5 байтов двух строк, сравнение проходит успешно. Но когда я сравниваю первые 6 байтов, это не удается. Мне интересно, что сохраняется в позиции 6-го байта, которая не работает.
buf
содержит"Hello\0"
? Ошибкаstrcmp
является довольно убедительным признаком того, чтоbuf
на самом деле не содержит того, что вы думаете. - person user4815162342   schedule 25.06.2014sizeof(ans)
, а неsizeof(buf)
? - person derhoch   schedule 25.06.2014s[c-1] != '\n'
неверен, если сервер отправляет более одной строки одновременно, как в"hello\nworld"
. Чтобы убедиться, что вы не пропустили строку, вы должны использоватьmemchr
илиstrchr
, чтобы найти новую строку в прочитанном вами вводе. - person user4815162342   schedule 25.06.2014\r\n
, поэтому ваш вывод будетHello\r\0
- person derhoch   schedule 25.06.2014Hello\r
изHello\r\n
, а затем заменяет последний символ вHello\r
на '\0', делая егоHello\0
. По крайней мере, теоретически это то, что делает код. - person user1720897   schedule 25.06.2014s[c-1] == '\n'
, а затем устанавливаетs[c-1] = '\0'
, поэтому, если раньше было\r\n
, в конце будет\r\0
. - person derhoch   schedule 25.06.2014Hello
в командной строке telnet, не гарантирует, чтоHello
окажется вbuf
. У вас может быть ошибка вread_in()
или где-то еще в программе, которая неправильно заполняетbuf
, илиtelnet
(как указывали другие)telnet
может отправлять дополнительный символ возврата каретки по сети. С другой стороны,strcmp(buf, "Hello")
, возвращающее ненулевое значение, в значительной степени является гарантией того, чтоbuf
в этот момент не начинается сHello\0
. - person user4815162342   schedule 25.06.2014\r\n
, по крайней мере, если он соответствует соответствующему RFC. - person alk   schedule 25.06.2014