Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Закачка файла средствами TClientSocket


Автор: Igor84 28.2.2011, 12:18
Пытаюсь реализовать загрузку файла с http сервера:
Код

    void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket)
    {
    int iSize = Socket->ReceiveLength();
     
    void *pvBuf = malloc(iSize);
     
    int iRes=Socket->ReceiveBuf(pvBuf,iSize);
     
    if (fHead)
    {
    fHead=0;
    void *pvTmp=pvBuf;
     
    char *ptr;
    ptr=strstr((char*)pvBuf,("HTTP/1.1 200"));
    if (ptr>0)
    {
    Form1->Memo1->Lines->Add("OK");
    pvBuf=strstr((char*)pvBuf,"\r\n\r\n")+4;
    int Count=iRes-((char*)pvBuf-(char*)pvTmp);
    Form1->Memo1->Lines->Add("count="+IntToStr(Count));
    TFileStream *str = new TFileStream(ExtractFilePath(Application->ExeName)+"33.tmp",fmCreate);
    str->Seek(0,soFromEnd);
    str->WriteBuffer(pvBuf,iRes-((char*)pvBuf-(char*)pvTmp));
    delete str;
    free(pvBuf);
    free(pvTmp);
    }
    else
    {
    Form1->Memo1->Lines->Add("NO");
    }
    }
    else
    {
    TFileStream *str = new TFileStream(ExtractFilePath(Application->ExeName)+"33.tmp",fmOpenWrite);////***(2)***
    str->Seek(0,soFromEnd);
    str->WriteBuffer(pvBuf,iRes);
    delete str;
    free(pvBuf);
    }
    }

Появилось несколько вопросов:
1. При успешном завершении загрузки файла сокет закрывается автоматически или его надо закрывать вручную? И в каком методе это делать и каким способом (Socket->Close() или Socket->Active=false)?
2. Выполнив запуск закачки в логе событий (Event Log) Билдера можно видеть, что запускается поток (Thread Start):
http://img256.imagevenue.com/img.php?image=50819_EventLog_122_18lo.jpg
Вопрос - почему не происходит Thread Exit?

Автор: Alca 28.2.2011, 14:15
Цитата

При успешном завершении загрузки файла сокет закрывается автоматически или его надо закрывать вручную? 

вручную

Цитата

И в каком методе это делать и каким способом (Socket->Close() или Socket->Active=false)?

как тебе больше нравиться

Автор: Igor84 28.2.2011, 15:53
Цитата(Alca @  28.2.2011,  14:15 Найти цитируемый пост)
вручную

Ок. Бросил на форму кнопку и в обработчике пишу:
Код

Form1->ClientSocket1->Active=false;

а в событии OnDisconnect компонента TClientSocket пишу:
Код

ShowMessage("Disconnected!");

При выполнении все происходит правильно, после Active=false появляется окошко с указанным сообщением. По идее все правильно, но в логе поток не завершается. Почему?

Автор: borisbn 1.3.2011, 16:54
Цитата(Igor84 @  28.2.2011,  15:53 Найти цитируемый пост)
По идее все правильно, но в логе поток не завершается. Почему?

у меня в чистом пустом проекте стартует 5 потоков, а по выходу из программы завершается только 4. Я бы на твоём месте не заморачивался. Если хочешь отловить leak'и, то используй CodeGuard (включается в опциях проекта)

Автор: Alca 1.3.2011, 19:13
Цитата

но в логе поток не завершается. Почему?

а че это за поток, это типа ClientSocket1 создает свой тред?

Добавлено через 2 минуты и 42 секунды
а если сделать
Код

ClientSocket1->Close();
 ?

Добавлено через 4 минуты и 6 секунд
запусти вне IDE  и глянь в диспетчере задач чего там, сколько там потоков

Автор: Igor84 1.3.2011, 22:46
Цитата(Alca @  1.3.2011,  19:13 Найти цитируемый пост)
это типа ClientSocket1 создает свой тред?

Ну, выходит, что так... Только не останавливает его, даже если создавать образец TClientSocket динамически, а затем в конце работы удалять его, согласно логу поток не завершается...
И даже если:
Код

ClientSocket1->Socket->Close();

тоже самое.
Цитата(Alca @  1.3.2011,  19:13 Найти цитируемый пост)
запусти вне IDE  и глянь в диспетчере задач чего там, сколько там потоков 

Попробовал, но это сложно сказать, т.к. в ОС работает много программ и служб, которые периодически запускают\останавливают свои потоки, поэтому сложно отследить - завершился\создался поток моей программы или нет...
Так что же это? Баг компонента?

Автор: borisbn 1.3.2011, 22:51
Цитата(Igor84 @  1.3.2011,  22:46 Найти цитируемый пост)
 даже если создавать образец TClientSocket динамически, а затем в конце работы удалять его, согласно логу поток не завершается...

так в этом просто убедиться:
Код

for ( int i = 0; i < 100000; i++ ) {
    TClientSocket * p = new TClientSocket();
    delete p;
}

при этом создаётся 100 тыс. потоков ? а даже если и создаётся, то завершается 100 тыс. раз ? 

Автор: Igor84 1.3.2011, 23:37
borisbn, согласен, но лог событий, кажется это не фиксирует.

Автор: Alca 1.3.2011, 23:40
Цитата

borisbn, согласен, но лог событий, кажется это не фиксирует.

 smile  так зафиксируй его

Добавлено через 14 минут и 44 секунды
составь протокол  smile 

Автор: Alca 1.3.2011, 23:56
Цитата

или нет...

или нет

Добавлено через 48 секунд
Цитата

Так что же это? Баг компонента?

передача что, где, когда

Автор: Igor84 2.3.2011, 00:36
Цитата(Alca @  1.3.2011,  23:56 Найти цитируемый пост)
передача что, где, когда

Очень смешно. Если по теме больше нечего сказать, лучше помолчать.

Автор: Alca 2.3.2011, 18:09
Цитата

поэтому сложно отследить

ни разу

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)