Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C++ Builder > Передача файлов по сети |
Автор: Sicrum 18.3.2008, 16:17 |
В общем надо передавать файл джпег по сети (точнее несколько файлов, 8-16 штук подряд). Пакетами по 1024 байта. Первые 10 байт каждого пакета - это слово, определяющее назначение данных в пакете. Для работы в сети используются ТСерверСокет и ТКлиентСокет. Итак порядок действий: • Клиент посылает запрос на рисунок • Сервер делает следющее - Высылает пакет с командой imagestart, именем и размером файла - Высылает сам файл с командой imagebytes и остаток пакета наполняется 1014 байтами с файла. Разумеется это делается в цикле до конца файла. Получается много пакетов с заголовком imagebytes - Высылает пакет imageend Эти 3 шага тоже выполняются в цикле, но по числу отправляемых файлов • Клиент делает следющие шаги в ответ на принятые - imagestart. Создает поток связанный с файлом - imagebytes. Записывает в открытый поток порцию полученных данных - imageend. закрывает поток и соответственно файл Вроде бы всё предельно просто, ТСР сохраняет и гарантирует порядок и доставку пакетов, НО...что получается на самом деле: пакеты доставляются странно. Некоторые рисунки передаются норм, а некоторые криво, причем очень. Но всегда передается правильно 1-2 первых пакета. Я пробовал ставить брейкпоинт на приемке imageend и к моменту первой остановки уже создается 3-5 файлов. Отсюда я сделал вывод что пакеты ПУТАЮТСЯ! то есть до того как придет первый Imageend приходит несколько Imagestart и потом все файлы сбиваются. У кого какие идеи??? Как можно еще передавать рисунки пакетами по 1024 байта или мож я где то ошибся или недопонимаю что то? |
Автор: Sicrum 18.3.2008, 16:54 |
Вся программа уже написана под СерверСокет и КлиентСокет, вот осталось только реализовать передачу картинок. Переписывать под что то другое к сожалению нет ни времени, ни желания =(( |
Автор: mes 18.3.2008, 16:57 |
Без приведения участков кода трудно сказать где ошибка поэтому для начала хотелось бы увидеть циклы отправки и приемки сокет-сообшения П.С. Несмотря на сохранненый порядок байтов, на вход сокета пакет может быть доставлен кусками |
Автор: Sicrum 18.3.2008, 17:07 |
СЕРВЕР (всё нижеприведенное выполняется в цикле): memset(buff,NULL,1024); sprintf(buff,"IMAGESTART"); // здесь добавляется имя и размер Socket->SendBuf(buff,1024); //здесь в pszBuffer заносится всё содержимое файла cnt=10; sprintf(buff,"IMAGEBYTES"); for (int k=0;k<iBytesRead;k++) { buff[cnt]=pszBuffer[k]; cnt++; if (cnt==1024) //если 1024 байта заполнены, то отсылаем и обнуляем счетчик буфера { cnt=10; Socket->SendBuf(buff,1024); memset(buff,NULL,1024); sprintf(buff,"IMAGEBYTES"); } } Socket->SendBuf(buff,1024); //высылаем остатки файла //команда конца рисунка memset(buff,NULL,1024); sprintf(buff,"IMAGEEND"); Socket->SendBuf(buff,1024); ============================================================================================= КЛИЕНТ: здесь в переменную S извлекается команда из буфера buff в который читается 1024 байта. if (S=="IMAGESTART") { // здесь извлекается имя и размер файла AnsiString adr=ExtractFileDir(Application->ExeName)+"\\sch\\"+PicID+".jpg"; Data = new TFileStream(adr,fmCreate); } if (S=="IMAGEBYTES") { for (int i=0;i<1014;i++) buff[i]=buff[i+10]; //уничтожаем в буфере команду путем простого смещения данных. остается 1014 байт if ((Data->Size+1014)<=DataSize) Data->Write(buff,1014); //далее проверяем вдруг это последний пакет else { Data->Write(buff,DataSize%1014); //если он последний то тогда нам надо не 1014 байт а остаток от деления размера файла на 1014 } } if (S=="IMAGEEND") //рисунок принят, удаляем поток { delete Data; Data=NULL; } |