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

Вниз

Отправка файла NMStrm   Найти похожие ветки 

 
Smile   (2003-06-04 08:48) [0]

Уважаемые мастера!
Задача в следующем, необходимо отправлять 1,2..n файлов
на другой комп в сети. Пичем отправка должна идти автоматом.
Программа мониторит папку и, если находит файл(ы) отправляет.
Вот процедура передачи

procedure TForm1.Timer1Timer(Sender: TObject);
var
c1,c2,Mask: string;
SR: TSearchRec;
myFile: TMemoryStream;
begin
Mask:=SendDir+"\*.*";
if FindFirst(Mask,faAnyFile,SR)=0 then
repeat
if SR.Name="." then continue
else if SR.Name=".." then continue;
NMStrm1.FromName :=SR.Name;
myFile:=TMemoryStream.Create;
myFile.LoadFromFile(SendDir+"\"+SR.Name);
NMStrm1.PostIt(myFile);
myFile.Free;
c1:=SendDir+"\"+SR.Name;
c2:=OutBoxDir+"\"+SR.Name;
CopyFile(PChar(c1),PChar(c2),false);
DeleteFile(c1);
WriteLog("Файл "+c1+" отправлен");
until FindNext(SR)<>0;
FindClose(SR);
end;

Вот процедура приема на удаленном компе:
procedure TForm1.NMStrmServ1MSG(Sender: TComponent; const sFrom: String;
strm: TStream);
var
myFile: TMemoryStream;
begin
aname:=sFrom;
MyFile:=TMemoryStream.Create;
MyFile.CopyFrom(strm, strm.size);
MyFile.SaveToFile(ReceiveDir+"\"+aname);
MyFile.Free;
WriteLog("Принят файл "+aname);
Memo1.Lines.Add(aname);
if not Form1.Active then Form1.Show;
end;

Отправляется только 2 файла, затем программа виснет!
Не пойму где проблема


 
Digitman   (2003-06-04 09:52) [1]

1. "Виснет" на какой строчке ? на PostIt ?
2. Почему не обрабатываешь событие OnMessageSent() ? Только пофакту его возникновения ты имеешь право (и то - с определенными оговорками) "переданный" удалять файл !


 
Smile   (2003-06-04 12:30) [2]

Убрал удаление файлов. Такая же ситуация. Виснет на PostIt
В отладчике сообщение "ESockError with message "10038:Socket operation on non-socket""
А в OnMessageSent я обрабатываю запись в лог-файл, что файл отправлен.


 
Digitman   (2003-06-04 12:42) [3]

попробуй-ка для начала выполнять все это не в обработчике таймера, по нажатию кнопки


сдается мне, что ты допускаешь повторный вызов обработчика таймера из-за неблок.реализации PostIt() и слишком малого периода таймера


 
Smile   (2003-06-04 12:52) [4]

Раньше так и было. По кнопке все работает без проблем.
В том и суть, что все должно быть без участия пользователя.
Он кидает файл(ы) в папку и на этом его задача оканчивается.
А период таймера не менее 60 сек.


 
Digitman   (2003-06-04 12:59) [5]


> А период таймера не менее 60 сек.

... а период таймаута, связанного, скажем, с временным ухудшением АЧХ в модемной dial-up-линии связи, составил 90 сек

все это время модемы на обеих сторонах соединения не бросали трубу и пытались адаптироваться к несущей либо снизить символьную скорость ... и это время в очер.раз по прошествию очередных 60 сек тикнул таймер !)


посиди и подумай об асинхронности механизма неблок.вызова PostIt() и о том, для чего на самом деле существует событие OnMessageSent()... отнюдь не только для протоколирования !!!


 
Smile   (2003-06-04 13:07) [6]

Хорошо, посижу поковыряюсь.
Но эксперимент проходит не на модемной линии а в сетке.
Хоть локально на 127.0.0.1 отправляю/принимаю, хоть на другой комп.
А вот таймаут NMStrmServ1.TimeOut:=9000 не маловат?


 
Digitman   (2003-06-04 13:48) [7]

Да вопрос-то не в этом)... не в NMStrmServ1.TimeOut)

В ходе трассировки своего кода тебе не приходила парадоксальная мысль о том , что при передаче потока с загруженным в него файлом весьма значительного размера метод PostIt() выполняется подозрительно быстро, практически мгновенно ? При любой нагрузке на коммуникации в лок.сети ? ведь не может же на самом деле файл размером, скажем, 1Гб быть переданным по сети (даже по самой высокоскоростной и незагруженной ничем иным в этот момент !) практически мгновенно !?

Вот это и должно было бы тебя навести на мысль, что PostIt() на самом деле занимается не физической передачей (в самых худших условиях выполнение PostIt() заняло бы ощутимое время - секунды, минуты, десятки минут, а то и более), а разбивкой потока на фрагменты некоего опред.размера (см. GetSockOpt(SO_SNDBUF)) и постановкой очередных фрагментов в очередь на физическую передачу

После постановки в очередь первого же (как правило, весьма небольшого по ср. с размером файла) фрагмента потока PostIt() немедленно возвращает управление вызвавшему его код.потоку, который продолжает выполнять следующие операторы, вплоть до завершения процедуры-обработчика
Все это время передача очередных фрагментов потока происходит в фоновом режиме под управлением организованного "внутри" NM-объекта асинхронного событийного механизма. И как только последний фрагмент будет успешно поставлен в очередь на передачу (даже еще не передан физически, а просто успешно поставлен в очередь !), NM-объект возбудит событие OnMessageSent(), показывающее, что поток вычерпан полностью.

Кр.того

Return Value:
The return value of this function is an OK response from the server if the stream was received properly.

означает, что всякий раз при вызове PostIt() результат вызова показывает, был ли фактически поток передан принимающей стороне или механизм передачи потока еще продолжает работать в фоновом режиме

Ты же, не дождавшись ни того ни другого факта (OK-результата вызова PostIt() или события OnMessageSent) при очередном "тике" таймера пытаешься вновь инициировать механизм "передатчика" (работающего в этот момент в фоновом режиме !!) , что и приводит к отказу с вышеприведенной тобой диагностикой.



 
Smile   (2003-06-04 14:40) [8]

Все ясно, спасибо!




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

Форум: "Сети";
Текущий архив: 2003.08.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.008 c
1-33093
Nucl
2003-07-23 18:04
2003.08.11
изменение системной палитры


1-33111
clim
2003-07-29 23:44
2003.08.11
Timer + Api


1-33185
qwe
2003-07-28 20:17
2003.08.11
запуск через сеть


3-33068
hair
2003-07-18 16:04
2003.08.11
FB1.0.3 и IB60 рекурсия в триггере


11-33090
nsvi
2002-12-05 08:23
2003.08.11
Как программно перегенерировать меню?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский