Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];

Вниз

не могу передать файл через 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.038 c
2-1164145586
albertinio
2006-11-22 00:46
2006.12.10
Работа с Word.Application


2-1164036911
никв
2006-11-20 18:35
2006.12.10
adoquery в консоли


2-1163927657
Ded
2006-11-19 12:14
2006.12.10
вопросик


8-1146079729
Azeem
2006-04-26 23:28
2006.12.10
контурные треугольники


2-1164003387
lobach
2006-11-20 09:16
2006.12.10
ValueListEditor





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский