Delphi потоки вопрос по капчи

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by trigada, 13 Mar 2010.

  1. trigada

    trigada Banned

    Joined:
    23 Sep 2009
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Здраствуйте.
    Такой вопрос:
    Пытаюсь разобраться с написанием многопоточной программки, с помощью "Винсок". Потоки как бы сделал все норм. Мне нужно взять капчу и передавать ее на антигейт.ком, воспользовавшись
    кодом который показал GlooK, в одной из тем, мне удалось вытащить капчу, но в том коде как бы капча вытаскиваеться в файл, насколько я понял, то так, как прога многопоточная, то не хорошо создавать файлы капчи для каждого потока, а потом удалять. Т.е. мне нужно капчу в память "пихать" и делать post запрос на антигейт, но я никак не могу понять, каким образом.
    Вот код GlooKa чуть поправленный под мои требования:

    Code:
    function fWSRecv(wHost, wRequest, wPort: string ): integer;
    var
    hSocket: TSocket;
    wsData: TWSAData;
    hHost: PHostEnt;
    hAddr: TSockAddrIn;
    hTimeout: TTimeVal;
    iRead: integer;
    h : dword;
    rb : dword;
    hBuffer: array[0..MAX_BUF_LEN] of char;
    NewFile: file;
    begin
     WSAStartup($202, wsData);
     hSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     hHost := gethostbyname(PChar(wHost));
     hAddr.sin_family := AF_INET;
     hAddr.sin_port := htons(strtoint(wPort));
     hAddr.sin_addr := pinaddr(hHost^.h_addr^)^;
     hTimeout.tv_usec := 0;
     hTimeout.tv_sec := (REPLY_TIMEOUT mod 1000) * 1000;;
     setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO, @hTimeout, sizeof(ttimeval));
     connect(hSocket, hAddr, SizeOf(hAddr));
    //Data := '';
     Send(hSocket, wRequest[1], length(wRequest), 0);
    AssignFile(NewFile,'c:\capcha1.jpeg');
    Rewrite(NewFile, 1);
     while (TRUE) do
     begin
      FillChar(hBuffer, SizeOf(hBuffer), 0);
      iRead := Recv(hSocket, hBuffer, length(hBuffer), 0);
         rb := pos(#13#10#13#10, String(hBuffer));
    if rb > 0 then
    rb := rb + 3 ;
      BlockWrite(NewFile, hBuffer[rb], iRead - rb);
      if (iRead <= 0) then break;
     end;
     CloseFile(NewFile);
     CloseSocket(hSocket);
     WSACleanup;
     result := 0;
    end;
    1.Как капчу в память Jpeg?
    2.Насколька я понял, то эту функцию (function fWSRecv) не могут использовать несколько потоков одновременно?
    Т.е. нужно использовать критические секции для исключения одновременного доступа к файлам( или памяти) из разных потоков. Или делать Массивную память, допустим у меня все равно больше 100 потоков не будет, и под каждый поток делать какойто цикл создания памяти Jpeg, где i это номер потока.

    Мои мысли по поводу Jpeg:
    Мне вместо этого
    Code:
    BlockWrite(NewFile, hBuffer[rb], iRead - rb); 
    надо вставить например

    Code:
    streamresponse:=TMemoryStream.Create;
    while (TRUE) do
     begin
      FillChar(hBuffer, SizeOf(hBuffer), 0);
    iRead := Recv(hSocket, hBuffer, length(hBuffer), 0);
         rb := pos(#13#10#13#10, String(hBuffer));
    if rb > 0 then
    rb := rb + 3 ;
          streamresponse.WriteBuffer(hBuffer[rb],iRead - rb);
           if (iRead <= 0) then break;
       end;
     streamresponse.Position:=0;
     JPEG:=TJPEGImage.Create;   //создаем jpeg
     JPEG.LoadFromStream(streamresponse);
       result:=JPEG;
      streamresponse.Clear;
       JPEG.Free;
    3. И если можно в память картинку вставить, то как ее передать, так как на антигейт пост запрос такого вида :
    Code:
    multi:=Tidmultipartformdatastream.Create;
    multi.AddFormField('method','post');
    multi.AddFormField('key',apikey);
    multi.AddFile('file',filename,ftype);
    где filename- название файла?

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

    Сразу говорю Delphi тока начал учить, если что то не так не пинайте. Просто интересно было поработать с инди и посмотреть что это такое, а это только на дельфи. И в универе мы его не учим, учили С++, поэтому хочу посмотреть что за зверь такой делпфи.
     
  2. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Чтобы хранить картинку в памяти, юзай TMemoryStream
    Передать же в антикапчу картинку можно например вот так:
    multi.AddObject ('file', ftype, '',image, 'captcha.' + itype);
    где:
    'file' - название поля
    ftype - тип картинки, например 'image/pjpeg'
    image - ссылка на объект типа TMemoryStream, в котором хранится картинка
    'captcha.' + itype - название файла (значения в принципе не имеет)
     
  3. trigada

    trigada Banned

    Joined:
    23 Sep 2009
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Все норм сделал через память, но интересует еще ответ на 2-й вопрос.


    Можно ли функцию использовать одновреммено в потоках, или надо ставить крит. секции, и если надо ставить их то где? Там где происходит вызов этой функции, или в самой функции, там где заносим в память картинку?
     
  4. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    чем меньше критическая секция тем лучше
    синхронизация снижает производительность из
    за гонки за право первым захватить ресурс
    в то время как остальные потоки заблокируются
    общее правило таково свести к минимуму
    критический участок кода а в идеале рассмотреть
    решения без синхронизации если возможно данную задачу так перепроектировать ну или по крайней мере свести ее синхронизацию к минимуму
     
  5. Meecript_

    Meecript_ Banned

    Joined:
    29 Oct 2008
    Messages:
    194
    Likes Received:
    62
    Reputations:
    32
    Крит.секции не нужны.
    greki_hoy, это общие фразы. Узким местом в подобном софте обычно остается скорость инета.

    P.S.:
    ТС, я вот только не понял, если на сокетах пишешь программу, почему работа с антигейтом через инди? :)
     
    #5 Meecript_, 13 Mar 2010
    Last edited: 13 Mar 2010
  6. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Ограничивать надо доступ к глобальной переменной
    Тут же вроде обращений к глобальным переменным нет, каждый поток работает со своими переменными, следовательно
    критические секции не нужны.
     
  7. trigada

    trigada Banned

    Joined:
    23 Sep 2009
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Ясно.
    Думал что неважно с инди или нет, просто на антигейте сделано так, буду делать на сокетах функцию антигейт если нужно, это что то меняет ?
     
  8. Meecript_

    Meecript_ Banned

    Joined:
    29 Oct 2008
    Messages:
    194
    Likes Received:
    62
    Reputations:
    32
    Если не важно, то зачем прогу на сокетах писать? Можно на инди.
    Но если потоки не меняют значение глобальной переменной, то можно не синхронизировать.