Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.10;
Скачать: CL | DM;

Вниз

не могу передать файл через TServerSocket   Найти похожие ветки 

 
KyRo   (2006-11-17 17:20) [0]

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

Как исправить такую сетуацию ?

Вот код сервера и то как я посылаю файл

var
  ms:TMemoryStream;
begin
  // Клиент получает команду на передачу файла.
 if Socket.ReceiveText = "ldimg" then
 begin
   ms:= TMemoryStream.Create;
   try
     // Получаем данные на передачу.
     ms.LoadFromFile(ExtractFilePath(Application.ExeName)+"Img\"+Nomer+".cab");
     ms.Position:= 0;
     // Добавляем длину данных, чтобы клиент знал,
     // сколько данных будет передано
     // Добавляем #0 , чтобы можно было определить,
     // где заканчивается информация о размере.
     Socket.SendText(IntToStr(ms.Size) + #0);
     // Посылаем его.
     Socket.SendStream(ms);
   except
     // Итак, осталось освободить поток, если что-то не так.
     ms.Free;
   end;
   Serverimg.Active:=False;


Вот код клиента и то как я принимаю и сохраняю файл
s, sl: string;
begin
 s:= Socket.ReceiveText;
 // Если мы не в режиме приёма:
 if Rec <> 5 then
 begin
   Rec := 5;
   // Теперь нам необходимо получить длину потока данных.
   SetLength(sl, StrLen(PChar(s))+1); // +1 for the null terminator
   StrLCopy(@sl[1], PChar(s), Length(sl)-1);
   DataSize:= StrToInt(sl);
   Data:= TMemoryStream.Create;
   // Удаляем информацию о размере из данных.
   Delete(s, 1, Length(sl));
 end;
 // Сохраняем данные в файл, до тех пор, пока не получим все данные.
 try
   Data.write(s[1], length(s));
   if Data.Size = DataSize then
   begin
     Data.Position:= 0;
     Data.SaveToFile("c:\img.cab");
     Data.Free;
     Rec:= 6;
     Socket.Close;
   end;
 except
   Data.Free;


 
Dmitrij_K   (2006-11-17 19:13) [1]

Отладчик тебе на что?


 
oldman ©   (2006-11-17 19:15) [2]


> И у меня постоянно выскакивает ошибка от того что переодически
> приходит пустая строка,а когда ошибки нет то размер послаемых
> данных не совподает с размером полученых.


активно ищем ошибку в коде.
она есть.
но мне ее искать как-то недосуг. уж извините...


 
MikePetrichenko ©   (2006-11-17 19:19) [3]

"Объясняю популярно" (С) Высоцкий

У сокетов есть внутренний буфер. И он совершенно не обязан совпадать с размером твоего файла или размером передаваемых данных.
Пакеты погут склеится а могут и не склеится. Может придни вместо одного пакета 10 мелкий.
Учи мат часть по сокетам.


 
KyRo   (2006-11-20 10:28) [4]


> Объясняю популярно" (С) Высоцкий
>
> У сокетов есть внутренний буфер. И он совершенно не обязан
> совпадать с размером твоего файла или размером передаваемых
> данных.
> Пакеты погут склеится а могут и не склеится. Может придни
> вместо одного пакета 10 мелкий.
> Учи мат часть по сокетам.


А как же их склеить и как это все проконтролировать , что бы файл пришол в нормальном виде ?


 
medved_68 ©   (2006-11-20 11:08) [5]


> А как же их склеить и как это все проконтролировать , что
> бы файл пришол в нормальном виде ?

KyRo делаешь считывание в буфер скажем размером 8192 байта. Считал, слил из буфера либо в поток либо на диск, и снова в цикле считываешь. И так до тех пор пока операция чтения буфера сокета не вернет количество считанных байт = 0. Это и есть условие выхода из цикла чтения. Ну а проверить размер данных можно, только если ты предусмотрел передачу этого размера с сервера. :)))


 
KyRo   (2006-11-20 11:12) [6]


> Dmitrij_K   (17.11.06 19:13) [1]
> Отладчик тебе на что?


Отладчик на сервере показывает что все ок . Файд загрузился в поток и отправлен.

А отладчик на клиенте показывает что приходит 3 или 4 пакета каждый по 8 килобайт. Таким образом посылаю файл 90 кило байт , а приходит около 30 !! Куда девались остальные ?


 
Сергей М. ©   (2006-11-20 11:14) [7]


> // Добавляем длину данных, чтобы клиент знал,
>      // сколько данных будет передано


Зачем это делать в текстовом виде ?

Посылай (см. SendBuf) для этой цели Int64-значение (ровно 8 байт, ни больше ни меньше) фактического размера передаваемого следом стрима.

На принимающей стороне сначала читай это Int64-значение  (см. ReceiveBuf) - оно укажет тебе полный размер передаваемого партнером стрима.


 
KyRo   (2006-11-20 11:19) [8]


> Зачем это делать в текстовом виде ?
>
> Посылай (см. SendBuf) для этой цели Int64-значение (ровно
> 8 байт, ни больше ни меньше) фактического размера передаваемого
> следом стрима.
>
> На принимающей стороне сначала читай это Int64-значение
>  (см. ReceiveBuf) - оно укажет тебе полный размер передаваемого
> партнером стрима.


Ну это да можно переделать так скорее будет лучше ! Но даже в моем варианте я знаю сколько данных должно прийти , а они не приходят в полном объеме ! Куда то теряются пакетов 5 ть.(судя по их размерам) ?


 
Alexander Panov ©   (2006-11-20 11:22) [9]


> KyRo   (20.11.06 11:19) [8]


В секцию except попадаешь?


 
Сергей М. ©   (2006-11-20 11:22) [10]


> Куда то теряются пакетов 5


Ты их сам теряешь.


 
KyRo   (2006-11-20 11:23) [11]


> активно ищем ошибку в коде.
> она есть.
> но мне ее искать как-то недосуг. уж извините...

Ошибка из за чего происходила я нашол и убрал . Там по правде была в коде я писал пустой буфер в поток.<


 
Сергей М. ©   (2006-11-20 11:23) [12]


> это да можно переделать


Не можно, а нужно !


 
KyRo   (2006-11-20 11:28) [13]


> Сергей М. ©   (20.11.06 11:23) [12]
>
> > это да можно переделать
>
>
> Не можно, а нужно !


Чем вызвана такая срочная не обходимость. Ошибки тут ведь нет . Я его позже переделаю .


> Alexander Panov ©   (20.11.06 11:22) [9]
>
> > KyRo   (20.11.06 11:19) [8]
>
>
> В секцию except попадаешь?


Нет ошибки не происходит ! Просто перестает происходить s:= Socket.ReceiveText; Из за этого количество даных что получил не совпадает с тем количеством которое должно быть и по этому файл не могу создать


 
KyRo   (2006-11-20 11:29) [14]


> Сергей М. ©   (20.11.06 11:22) [10]
>
> > Куда то теряются пакетов 5
>
>
> Ты их сам теряешь.


Может и сам !! Но не могу найти где !


 
Сергей М. ©   (2006-11-20 11:34) [15]


> Чем вызвана такая срочная не обходимость


Тем что твоя логика с Send/ReceiveText рано или поздно обречена на провал.


> Ошибки тут ведь нет


И здесь ошибка, и далее по тексту.

Например,

if Data.Size = DataSize then ...

А если не равно ?


 
KyRo   (2006-11-20 11:46) [16]


> > Чем вызвана такая срочная не обходимость
>
>
> Тем что твоя логика с Send/ReceiveText рано или поздно обречена
> на провал.


Ок Этим щас займусь


> if Data.Size = DataSize then ...
>
> А если не равно ?


А если не равно . Я не чего не делаю так как не могу сохранить файл он ведь принят не полностью.


 
Сергей М. ©   (2006-11-20 11:55) [17]


> он ведь принят не полностью.


А если размер файла > 2 гб ?


 
KyRo   (2006-11-20 12:26) [18]


> Сергей М. ©   (20.11.06 11:55) [17]
>
> > он ведь принят не полностью.
>
>
> А если размер файла > 2 гб ?


То есть предлогаете сохранять на диск что есть ?


 
Сергей М. ©   (2006-11-20 12:31) [19]


> предлогаете сохранять на диск что есть ?


Это единственное универсальное решение.
Причем для файлов значительного размера вполне может потребоваться организация прогресс-индикации приема-передачи, на стороне передатчика это реализуется простым наследованием TFileStream с перекрытием метода Write(), а вот на стороне приемника придется читать небольшими блоками равного размера, скажем, по 4 или 8 кбайт.


 
KyRo   (2006-11-20 12:59) [20]

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


Len:= Socket.ReceiveLength;
 GetMem(Bfr, Len);
 // Если мы не в режиме приёма:
        try
          Socket.ReceiveBuf(Bfr^, Len);
          Data.Write(Bfr^, Len);
          Rec:=True;
        finally
          Data.SaveToFile("c:\1.cab");
          FreeMem(Bfr);
        end;
 
end;


Сохраняю в любом случае файл на диск .
Так вот иногда приходит 24 килобайт , а иногда 48 но до размера файла 90 кб не доходит куда то деваются пакеты !!

Куда они деваются ?


 
Джо ©   (2006-11-20 14:06) [21]

Куда "деваются" пакеты — это тебе, конечно, виднее. А вот так
       finally
         Data.SaveToFile("c:\1.cab");

лучше не делать.


 
Сергей М. ©   (2006-11-20 14:50) [22]

Обработчик On[Client]Read;
var
 Buf: array[0..4095] of Byte; //можно сделать лок.переменной
...

Len:= Socket.ReceiveBuf(Bга, SizeOf(Buf));
case Len of
-1: .... крит.ошибка транспорта
0: Socket.Close;// партнер закрыл соединение по своей инициативе
else
 Data.WriteBuffer(Buf, Len); //получены очередные Len байт, запишем их в конец стрима (Data: TFileStream)
end;

....

end;


 
KyRo   (2006-11-20 15:21) [23]

ок буду пробовать



Страницы: 1 вся ветка

Текущий архив: 2006.12.10;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.033 c
2-1164360390
susergey
2006-11-24 12:26
2006.12.10
запуск программы


2-1163750376
Kostafey
2006-11-17 10:59
2006.12.10
Вопрос про сетку DBGrid


15-1163687787
Calibr
2006-11-16 17:36
2006.12.10
Физикам


2-1164375225
SergeyP
2006-11-24 16:33
2006.12.10
Как проиграть mailbeep?


15-1163698600
ProgRAMmer Dimonych
2006-11-16 20:36
2006.12.10
Microsoft готова уйти из Китая