2010-09-28 3 views
1

У меня есть общий вопрос о recv-функции winsock. Я пишу программу с клиент-серверной архитектурой, где клиент отправляет изображение камеры на сервер, и сервер отправляет другое изображение обратно клиенту. Клиент отправляет несколько изображений, пока программа не будет закрыта. И сервер будет отвечать на каждое полученное изображение другим изображением.recv-функция winsock

Клиент (отправить) ----> Сервер (получить) ----> Сервер (отправить) ----> Клиент (получить). ^ _ __ _ __ _ __ _ ____LOOP_ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _ |

Моя проблема - это функция приема серверов. Если я вызываю функцию приема несколько раз с большим буфером размером 512 бит, как узнать, что я получил изображение целиком? Примеры, которые я нашел, просто подождите, пока соединение не будет закрыто (recv возвращает 0), но я хочу получить несколько изображений, не закрывая соединение. Но если я получу до тех пор, пока в буфере не останется никаких байтов, функция recv остановит поток до появления новых байтов (но этого никогда не произойдет, потому что сервер сначала хочет отправить свое собственное изображение обратно клиенту перед получением следующий).

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

ответ

4

Разработка протокола с заголовком, который включает в себя размер n количества данных, которое должен ожидать получатель. Приемник только считывает заголовок PLUS n байт (обозначается заголовком) из TCP-потока. Тогда вы можете ожидать следующий заголовок. Если вы не получили эти n байт, передача не завершена.

Короче можно определить сообщение в своем протоколе следующим образом:

Сообщение:

  • длина данных (32 бит без знака целое)
  • содержания данных
+0

Вы также можете использовать escape-последовательности, но использование заголовка будет более эффективным. – sje397

+0

Простая структура, включая размер и буфер, подходит для этой проблемы или мне нужны серверные отправки/recv-вызовы для передачи одного изображения? – ben

+0

Я бы даже пошел с этим: заголовок проще реализовать, чем итерацию над содержимым данных для обработки/удаления управляющих последовательностей. – Robert

1

обертывания ваши данные изображения в пакете, состоящем из

  • фиксированного размера заголовка говорить, сколько байт будет следовать
  • фактические данные изображения

в вашем получить код, который вы сначала прочитать часть заголовка, то прочитать соответствующее количество данных.

пример кода с ошибкой проверки опущен; также вы должны всегда зацикливать фактический вызов recv, поскольку данные могут появляться на куски!

unsigned bytesExpected; 
Image imgData; 
while(!LoopMustStop) 
{ 
    Read(sizeof(unsigned), bytesExpected); 
    Read(bytesExpected, imgData); 
    Process(bytesExpected, imgData) 
} 
+0

Благодарим за быстрый пример, но на самом деле вам следует сохранить порядок байтов и размер заголовка ('sizeof (unsigned)' может меняться в зависимости от компилятора). Протокол может занять некоторое время. – Robert