Indy все-таки дерьмо?

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Xieon, 28 Apr 2010.

  1. Xieon

    Xieon New Member

    Joined:
    18 Aug 2009
    Messages:
    11
    Likes Received:
    1
    Reputations:
    0
    В общем, возникла задача слить с одного сайта большое количество файлов и перезалить в другое место. В качестве этого "другого места" был выбран Народ.Диск от яндекса (всякие айфолдеры и рапидшары по сравнению с ним - полное УГ, имхо). Файлов много, тысячи. Только не спрашивайте, зачем мне это :) Для затравки я написал скриптик на PHP+curl, ищущий, скачивающий и закачивающий файлы, он отлично работал, но скорость меня не устраивала, поэтому я переписал его на Delphi+Indy, процесс пошел гораздо веселее)

    Через полдня все файлы, наконец, перекачались, я расслабился, думал даже попить кофе...и тут мне в голову пришла мысль сверить хэши md5 у оригинальных файлов и закачанных на Народ, благо можно их прочитать на страницах файла, и что оказалось? У каждого пятого моего файла на Народе хэш не совпал (ровно 20%). Проверил - архивы действительно битые...Буквально 10-20 байт разница, но битые. Пи**ец.

    Народ - несмотря на свои преимущества, довольно криво работает и все же я не думаю, что настолько криво, что неправильно заливает файлы. И еще - я проверил, оказалось, что среди тех файлов, которые заливал PHP скрипт, ни одного битого нет. Судя по всему, проблема в Indy (IdHTTP). Да и я не раз слышал, что Indy, в котором и так багов куча, криво работает в потоках. Знающие люди, скажите, пожалуйста, это из-за него так?)

    Если из-за него, то на что переписать прогу? TClientSocket из VCL? Wininet? Winsock?

    P.S. Все HTTP-заголовки, отсылаемые прогой, совершенно идентичны тем, что отсылает браузер, проверено сниффером, так что дело не в них.
     
    #1 Xieon, 28 Apr 2010
    Last edited: 28 Apr 2010
  2. ZdezBilYa

    ZdezBilYa Elder - Старейшина

    Joined:
    29 Aug 2008
    Messages:
    198
    Likes Received:
    75
    Reputations:
    19
    Никогда никаких проблем по использованию Indy в потоках не было
     
  3. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Есть еще библиотека Synapse, но хз как она
    А вообще, перепиши все это на винсок, тогда если у тебя не будет получаться будешь винить только себя
     
  4. zeppe1in

    zeppe1in Elder - Старейшина

    Joined:
    12 Jul 2006
    Messages:
    343
    Likes Received:
    66
    Reputations:
    18
    Synapse круче инди. а на сокетах наверное запарно будет писать, хотя конечно же это лучший вариант.
     
  5. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Может быть ты не совсем правильно отправлял файл?
    Нужно анализировать все возможные ошибки, вплоть до того, что соединение может потеряться.
    Если честно, то я не считаю, что это ошибка Indy, хотя я не являюсь поклонником данного компонента.
     
  6. Xieon

    Xieon New Member

    Joined:
    18 Aug 2009
    Messages:
    11
    Likes Received:
    1
    Reputations:
    0
    Хм, ну а что я делаю не так? Все стандартно, создаю мультипарт-формдата, добавляю файл, делаю пост...Если оборвалось подключение или еще что-то - вываливается исключение, файл пропускается. Других способов контроля закачки там вроде нет.

    Synapse? Попробую, спасибо.
     
  7. alexpro2004

    alexpro2004 New Member

    Joined:
    13 Apr 2010
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    какая версия инди ?
     
  8. Xieon

    Xieon New Member

    Joined:
    18 Aug 2009
    Messages:
    11
    Likes Received:
    1
    Reputations:
    0
    Delphi 2009, там десятая вроде. Через SVN не обновлял.
     
  9. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    на винсок можно так две апи
    Code:
    download_file(... );
    upload_file(... );
    
    сделать их рабочими элементами пула потоков
    надо например скачaть делаеш асинхронный вызов
    Code:
    DOWNLOAD_INFO Args = malloc(sizeof(Args));
    Args.Link = strdup(link);
    Args/... еще что то
    QueueUserWorkItem(download_file, &Args, WT_SET_MAX_THREADPOOL_THREADS(0, 12));
    или
    QueueUserWorkItem(upload_file, &Args, WT_SET_MAX_THREADPOOL_THREADS(0, 12));
    
    и все следующие запросы в очередь можно ставить асинхронно
    можно например выдать 12 запросов на ввод вывод
    12 файлов скачается за время одного лиш бы канал позволял :)
    в чем плюс потоки не надо создавать и разрушать так часто
    после выполнения рабочего элемента этот же поток в пуле ждет следующий запрос
    а если нет свободных все 12 заняты вводом выводом и канал широкий
    то можно еще 12 добавить венда тут же создаст еще 12 потоков
    и передаст им рабочие элементы а после если долгое время запросов не будет
    начнет очищать пул от лишних потоков
    все это флагами одного из параметров QueueUserWorkItem
    регулируется :)

    а это пример download_file
    Code:
    unsigned long __stdcall download_file(DOWNLOAD_INFO *pArgs)
    {
    //... формируем post ну тут элементарно
    //... скачиваем тоже просто
    //... освобождаем память из под аргументов
    free(pArgs);
    return 0;
    }
    
    если у нас 42 потока висят на вводе выводе переключений контекстов нет
    имеет смысл столько создать если канал широкий за время 1 файла
    скачивать 42 :)

    ну и по такому же принципу написать upload_file :)
    должно мега быстро работать да и скачивать можно в три - 4 потока
    один файл если например сервер на одно соединение рубит скорость
    но поддерживает скачивание файлов по частям :)
     
  10. VernonCody

    VernonCody Banned

    Joined:
    30 Jul 2009
    Messages:
    68
    Likes Received:
    23
    Reputations:
    13
    Indy — говно. С потоками работает просто отвратно.
    Решение: ICS
     
  11. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Все ваши беды от незнания матчасти:
    1. Каждый объект инди ровным счетом ничего не знает о других объектах созданных в других потоках и существует независимо от них. По-этому утверждение "Indy — говно. С потоками работает просто отвратно." изначальное глупое, инди с потоками не работает вообще, программист с ними работает.
    2. Исключения - не ошибки, это средство языка, и их надо обрабатывать, иначе исключение валит поток.

    ЗЫ Главный недостаток инди - это работа через исключения, новички этого не понимают и пугаются. На месте разработчиков инди я бы использовал "тихий режим"
    ЗЫЫ А вот доставляет/принимает ли корректно данные - другой вопрос, и я на него не знаю ответа.
     
  12. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Причем тут матчасть, может имел введу незнание как работает Indy?
    не правда, взаимоотношение есть при создании и удалении объектов Indy(но там код идеален и багов вызвать не может)

    На счет indy - говно : indy не говно...так катяшок) Багов уйма в версии в Delphi 7. Само собой очень много чего исправлено в текущих версиях. Но на удивлении у ТС похожая ошибка что и у меня в древней версии. Короче по не понятным причинам при скачивании файла из инета у него действительно урезаются 10-20 байт. Причем происходит мягко говоря от балды. Если что то происходит в программе от балды, то по любому это от не правильной синхронизации потоков. А не правильная синхронизация бывает если программист тупо не знает как правильно синхронизировать или тупо ошибся. На синхронизации собаку съел, до сих пор не могу найти где урезается. Кстати поговаривали что проблема с SysUtils, точнее с одной процедурой. Скачал этот модуль с данным фиксом - заработало gzip декомпрессия, а с урезанием "binary" данных не решил пока.
     
  13. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Может дашь четкое определение выражения "матчасть", тогда я тебе скажу что я имел ввиду
    Тыкни в это место, я такого не замечал
    Чтобы этого избежать нужно разрабатывать такую архитектуру в которой синхронизация не понадобится, ну или почти не понадобится.
    У мну как-то изначально она работала, может потому что у меня дельфи 2009 и инди постоянно обновляю, хз.

    Так-то баги конечно есть, но они не критичные. Вот например стандартный куки менеджер не использую, пришлось припилить свой, т.к. тот не со всеми сайтами корректно работал и авторизация по кукам проваливалась, несмотря на все обновления.
    Ну да, я заметил это по количеству тем открытых тобой про сокеты ;)
     
    #13 GhostOnline, 2 May 2010
    Last edited: 2 May 2010
  14. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    На сокетах все в стопятсот раз проще + развивается знание rfc.
     
  15. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    На сокетах не проще, но эффективнее и при правильной логике работы будет 100% работать.
     
  16. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Туплю
    Версия для D7, так что в твоей может что то поменяли.
    Файл IdComponent.pas : смотри конструктор и деструктор.
    Если было бы всё так просто, то синхронизация не нужна была бы. Конечно всегда её сводят к минимуму, но без неё во многих задачах ни как.
    Естественно.
    Я вообще не вижу смысла использовать их куки менеджер, если свой код в 200-300 строк(могу дать), и не надо создавать лишних классов.
    Согласен, RFC и API рулят, т.к. код свой, нет боязни что где то там что то не так работает, и собственно размер приложения существенно уменьшается. Но опять же изобретать велосипед не хочется, я думаю нужно просто написать свой маленький движок и юзать его.
    Када indy писали, тоже думали что при правильной логике работы будет 100% работать)
     
  17. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Ну так или иначе, если ты верно реализуешь работу своего сокетного движка, предотвратишь возникновение всевозможных ошибок, то твой вариант будет совершенно правильно работать, никаких проблем не будет возникать.

    Вот разработчики Indy в реале немного странно поступили. К примеру, есть ошибка в Indy 9 (точной версии не знаю, знаю, что в 10-ой этой проблемы уже нету). В классе TIdMultiPartFormDataStream, который используется для работы с Multipart forms дописывались два дополнительных ненужных байта, к одному из параметров, что почти всегда влияло на результат работы.

    Можете прочитать об этом хотя бы здесь: http://forum.vingrad.ru/act-ST/f-86/t-287613.html
     
  18. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Все так просто =) Пробовал в потоках только запросы выполнять?
    Куки менеджер это я так выразился чтобы было понятней, на самом деле процедура
    строк в 50, не стал морочиться с доменами, потому что каждый объект у меня строго для одного домена
    Такой уже есть - Synapse, так что опять велосипед.
    Это цветочки
    http://janych.selfip.com/Examples/Delphi/Indy/HTTP/
    Хоть и про неактуальную версию, но сам факт наличия таких багов обескураживает.
     
    #18 GhostOnline, 7 May 2010
    Last edited: 7 May 2010
  19. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Я такое часто использую, опять же по возможности, бывает что и обработку надо делать многопоточно.
    Synapse - уг, там единственно стоящее SSL удобно сделан, а работа с соксами и http-прокси достаточно проблематична если использовать их HTTP компонент. Если бы он хорошо поддерживал последнее и поддерживал gzip/deflate - я бы безусловно использовал бы его.
    Читали, знаем)
     
  20. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Обоснуй, на основе чего у тебя сложилось мнение, что Synapse неправильно работает с прокси? И этот компонент нельзя назвать, как ты выразился "УГ", - он довольно стабильно работает.