2012-02-12 4 views
0

Итак, у меня есть этот кусок кода, который будет просто прочитать сообщение от клиента и ответ с «да»C сервер странное поведение

while(strcmp(buffer, "QUIT") != 0){ 
    bzero(buffer, 255); //cleans the read buffer 

    /*this reads the aux (request) from the client*/ 
    recv(newsockfd, buffer, 255, 0); 

    if(strlen(buffer)) 
     printf("Thread %d: %s\n", thread_no, buffer); 
    fflush(stdout); 

    write(newsockfd, "yup\n", 4); 
} 

Проблема в том, что в самом первом чтении все идет хорошо, но все остальные чтения испорчены, если я отправляю сообщение «гитара», например, он получает «g», петли, а затем получает «uitar», отправляя другую «yup».

У меня нет понятия, что происходит.

+1

Что, по вашему мнению, предотвращает такое поведение в вашем коде? –

ответ

6

Короткий рассказ: TCP не является ориентированным на сообщение протоколом, это протокол, ориентированный на поток. Сообщения могут быть фрагментированы или объединены вместе, и ваше приложение должно иметь дело с этим (единственная гарантия заключается в том, что вы получите данные в том же порядке, который вы его отправили).

+0

Или, как можно проще, вы забыли разработать и реализовать протокол, который требует семантики. –

0

recv() считывает как можно больше данных. Вы должны прочитать, пока не нажмете EOF, ошибку или новую строку. Только если у вас есть эта новая строка, у вас есть полная строка, которую вы затем сравниваете с «QUIT», и которую вы признаете с помощью «Yup».

0

Три других ошибки в фрагменте кода выше.

1) Не проверять возвращаемое значение из recv(). Сокет мог быть закрыт грациозно (возвращаемое значение == 0), получил ошибку (возвращаемое значение == -1) и т. Д. Еще важнее то, что вы не должны предполагать, что вы получите все 4 байта «QUIT» сообщение, отправленное удаленным вызовом отправки. Вы можете получить только «Q».

2) Если recv() должен был получить 255 символов (ни один из которых не является нулевым символом), то последующий strlen() будет считывать недопустимую память и, возможно, сбой.

3) Не проверять возвращаемое значение вызова для записи.

Смежные вопросы