2016-09-01 2 views
-1

Я пытаюсь изучить модель клиентского сервера в Linux, и у меня есть два файла C, а именно server.c и client.c. Это фрагменты кода, с которыми у меня возникают проблемы.Как отправить и получить символ новой строки поверх сокетов в модели клиентского сервера?

server.c фрагмент кода

char* message = "<query>\n"; 
write(client_socket_filedescriptor, message, sizeof(message)); 

client.c фрагмент кода

char* message = "<query>\n"; 
read(socket_filedescriptor, buffer, sizeof(buffer)); 
printf("%s", buffer); 
printf("\n\n"); 
printf("%s", message); 

Теперь, когда я бегу мой сервер и затем, когда я бегу мой клиент, я ожидаю, что PRINTF заявления для печати те же строки, что и <query>\n, но я продолжаю получать разные выходы для buffer и message переменных.

Результат выглядит примерно так, когда я запускаю код клиента.

Output image

Как вы видите, эти две строки различны. Я пытаюсь смоделировать типичное рукопожатие TCP, и я хочу убедиться, что эти две строки одинаковы, а затем клиент начнет писать или что-то делать с этим сервером. Но у меня есть эта тривиальная проблема. Может ли кто-нибудь сказать мне, как его решить? Я планирую использовать strcmp для сравнения переменных буфера и сообщения, но, поскольку он стоит сейчас, strcmp не возвращает 0, поскольку это разные строки afterall.

+1

'sizeof (message)' -> 'strlen (message) + 1' – kaylum

+0

Значит, вы должны изменить' sizeof (message) 'на' strlen (message) '? Если это так, я получаю сообщение об ошибке, поскольку чтение звонка - только чтение первого символа. – posixKing

+0

Да, вам нужно изменить это - 'sizeof (message)' дает размер указателя, а не то, на что он указывает. Если вы все еще получаете ошибки, то, очевидно, в вашей программе есть другие ошибки. Например, распространенная ошибка предполагает, что 'read' всегда будет получать все сообщение. 'read' должен всегда вызываться в цикле с проверенным возвращаемым значением, чтобы определить, сколько байтов было прочитано. Предоставьте [mcve], если вы хотите получить дополнительную помощь. – kaylum

ответ

0

Вы игнорируете счет, возвращаемый read(). Он может быть -1, указывая на ошибку или ноль, указывающий конец потока, или положительное число, указывающее, сколько байтов было получено. Вы не можете предположить, что read() заполняет буфер, или что один send() или write() соответствует одному recv() или read().

Подробно:

write(client_socket_filedescriptor, message, sizeof(message)); 

Вы только отправка четыре байта, размер указателя. И вы игнорируете возвращаемое значение. Он должен быть

int count = write(client_socket_filedescriptor, message, strlen(message)); 
if (count == -1) 
    perror("write"); // or better 

char* message = "<query>\n"; 

read(socket_filedescriptor, buffer, sizeof(buffer)); 

Это должно быть

int count = read(socket_filedescriptor, buffer, sizeof(buffer)); 
if (count == -1) 
    perror("read"); // or better 
else if (count == 0) 
    ; // end of stream: the peer has disconnected: close the socket and stop reading 
else 

Назад к коду:

printf("%s", buffer); 

Это должно быть

printf("%.*s", count, buffer); 

Я планирую использовать strcmp()

Вы должны планировать использовать strncmp() с count выше в качестве параметра длины. В любом случае вы не можете считать, что ввод заканчивается с нулевым значением, если вы (а) не должны посылать нуль, которого вы не являетесь, и (b) писать цикл чтения, который останавливается, когда вы его читаете.

+0

Операторы printf, которые вы передали как буфер, так и переменные сообщения, одинаковые, но когда я удаляю ваш синтаксис '. *' Вместе с count (только в printf), я возвращаю старый вывод снова, что означает, что ваш код просто форматирует printf операторов, но буфер и сообщение никогда не содержат одинаковых строк. Есть ли способ, которым я могу убедиться, что я читаю только « \ n', а не некоторые лишние странные символы? – posixKing

+0

@lufork Вы не получили никаких дополнительных странных символов. Они уже были там, и вы напечатали их, потому что ваш вызов 'printf()' был неправильным. Оператор 'printf()', который я дал, является правильным, поскольку он ограничивает то, что выводится на то, что было фактически получено, т. Е. 'Count' bytes. Вы должны использовать ту же верхнюю границу при копировании или другой обработке этого буфера, в любом коде, который у вас может быть для того, который не был отправлен, вместо того, чтобы предполагать, что 'read()' заполнил буфер, как я уже сказал. Я могу только прокомментировать код, который вы опубликовали. – EJP

+0

О, это имеет смысл. Благодарю. – posixKing