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

Вниз

Подвисание приложения во время передачи файла...   Найти похожие ветки 

 
SeNtiMeL   (2003-02-03 03:06) [0]

Когда начинаешь передавать файл через Socket.SendStream то подвисает окно программы на время передачи. Как этого избежать.
То же самое происходит и при получениии файла клиентом.
В программах типа IRC отправка файла происходит просто здорово без зависаний и т.п....
Как сделать без зависаний ?


 
ole   (2003-02-03 05:39) [1]

Отправляй в отдельном Thread"е


 
Digitman   (2003-02-03 11:26) [2]

либо используй неблок.режим гнезда в осн.код.потоке

см. событие OnWrite()


 
SeNtiMeL   (2003-02-03 17:38) [3]

а если не сложно приведите пример...


 
ole   (2003-02-04 04:55) [4]

Создай Thread: (очень просто)
В методе Execute организуй отправку.
Передать данные потоку, я думаю, не проблема


> см. событие OnWrite()

Если по совету Дижитмэна, то, скорей всего, SendStream не прокатит. Там придется посылать поблочно, ожидая события OnWrite, которое скажет тебе, что очередь передачи свободна и ты можешь кинуть новую порцию данных.


 
Digitman   (2003-02-04 08:17) [5]


> ole



> скорей всего, SendStream не прокатит


Прокатит. Ничто не мешает в событии OnWrite() дописать, если нужно, в "хвост" еще не полностью переданного потока и тут же вновь вызвать этот же SendStream()


 
ole   (2003-02-04 12:20) [6]


> и тут же вновь вызвать этот же SendStream()

Тогда непонятен смысл твоего предложения. У него все виснет и так, а ты предлагаешь что б вообще все повисло.
Как я понимаю, пока не отправится весь блок данных через SendStream, буфер передачи будет постоянно занят (полон).
Другое дело, если отправлять буфера, то всегда можно увидеть через OnWrite, что следует отправить еще один и тд и тп.
И еще, SendStream освободит хэндл, данный ему для передачи данных, что же ты предлагаешь ему отправлять???


 
Digitman   (2003-02-04 13:43) [7]


> ole



> У него все виснет и так, а ты предлагаешь что б вообще все
> повисло.


Не говори ерунды. Ничего не повиснет. Заполнение 8к-буфера происходит мгновенно. После этого send-метод в любом случае вернет управление, даже если требуется к передаче в сотни и тысячи раз больше данных.


> Как я понимаю, пока не отправится весь блок данных через
> SendStream, буфер передачи будет постоянно занят (полон).
> Другое дело, если


Неверно понимаешь. Смотри реализацию SendStreamPiece, прежде чем рассуждать и делать выводы.


> Другое дело, если отправлять буфера, то всегда можно увидеть
> через OnWrite, что следует отправить еще один и тд и тп.


Чем тебе TMemoryStream не буфер ? Передал его в метод SendStream(), получил назад управление, проанализировал результат.

Читаем хэлп :

The value returned by SendStream indicates whether any information was successfully written to the connection.

Что, трудно так понять ? True - весь поток передан. False - частично. Если частично, то это означает, что stream-объект еще не разрушен и можно обратиться к любым его св-вам (например, Write для записи в поток доп.данных), в т.ч. св-ву Position (покажет, сколько реально данных на этот момент "вытолкнуто" через буфер передачи в канал)

И, если частично, то не следует "пыжиться", пытаясь следом же вызвать снова SendStream для передачи оставшегося фрагмента потока. Следует дождаться OnWrite и тогда уж вызывать SendStream для ТОГО ЖЕ объекта stream С ТЕМ ЖЕ его св-вом Position, чтобы SendStreamPiece продолжил чтение очер.порции потока в буфер передачи С ТОГО ЖЕ места, с которого предыдущая попытка оказалась неуспешной.


 
Digitman   (2003-02-04 13:50) [8]

Вот фрагменты кода, работающего с использованием SendStream в неблок.режиме



TOutgoingMemStream = class(TMemoryStream)
private
FOnDestroy: TNotifyEvent;
public
constructor Create(OnDestroy: TNotifyEvent);
destructor Destroy; override;
end;
...


constructor TOutgoingMemStream.Create(OnDestroy: TNotifyEvent);
begin
inherited Create;
FOnDestroy := OnDestroy;
end;

destructor TOutgoingMemStream.Destroy;
begin
if Assigned(FOnDestroy) then
FOnDestroy(Self);
inherited Destroy;
end;

...

procedure TSocketTransport.DoOnOutgoingStreamDestroyed(Sender: TObject);
begin
FOutgoingStream := nil;
end;

// DataBlock sender
function TSocketTransport.Send(const Data: IDataBlock): Integer;
var
StreamToSend: TMemoryStream;
StreamSize: DWord;
CurPos: DWord;
WaitEvent: THandle;
begin
Result := 0;
if Assigned(Data) then
begin
if ((Data.Signature and CallSig) = CallSig) and (Data.Context = 0) then
begin
WaitEvent := CreateEvent(nil, False, False, nil);
Win32Check(WaitEvent <> 0);
Data.Context := WaitEvent;
end;
Result := Data.Context;
InterceptOutgoing(Data);
StreamToSend := TMemoryStream(Data.Stream);
StreamSize := StreamToSend.Size;
LockOutStream;
try
if not Assigned(FOutgoingStream) then
FOutgoingStream := TOutgoingMemStream.Create(DoOnOutgoingStreamDestroyed);
try
CurPos := FOutgoingStream.Position;
FOutgoingStream.Position := FOutgoingStream.Size;
FOutgoingStream.WriteBuffer(StreamToSend.Memory, StreamToSend.Size);
FOutgoingStream.Position := CurPos;
FWinSocket.SendStream(FOutgoingStream);
except
FOutgoingStream.Free;
raise;
end;
finally
UnLockOutStream;
end;
end;
end;


// OnWrite handler

procedure TSocketTransport.WriteEventHandler(Sender: TObject; Socket: TCustomWinSocket);
begin
try
Socket.SendStream(FOutgoingStream);
except
FOutgoingStream.Free;
raise;
end;
end;



 
SeNtiMeL   (2003-02-05 02:43) [9]

Спасибо тебе большое :)


 
ole   (2003-02-06 14:00) [10]

ДиджитМэн:
Спасибо. Действительно все просто.
Вот, если б все твои коментарии были такими подробными... :)


 
Digitman   (2003-02-06 16:44) [11]


> ole


Конечно, просто)

Вот если бы все программеры взяли бы за полезную привычку, когда что-то непонятно, заглядывать в документацию и исх.тексты)...



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

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

Наверх




Память: 0.48 MB
Время: 0.007 c
7-88281
Калашников Игорь
2003-02-02 04:44
2003.03.27
Hint ы, собаки блин


1-87898
ghg
2003-03-13 08:41
2003.03.27
Нетипизированный файл и Tbitmap


14-88212
Vlad-mal
2003-03-11 17:38
2003.03.27
FastReport


3-87783
reticon
2003-03-11 11:29
2003.03.27
использование файлов excel


3-87838
dums
2003-03-10 08:00
2003.03.27
много потоков на одну базу данных :))





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