Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Delphi потоки вопрос по капчи (https://forum.antichat.xyz/showthread.php?t=186355)

trigada 13.03.2010 06:06

Delphi потоки вопрос по капчи
 
Здраствуйте.
Такой вопрос:
Пытаюсь разобраться с написанием многопоточной программки, с помощью "Винсок". Потоки как бы сделал все норм. Мне нужно взять капчу и передавать ее на антигейт.ком, воспользовавшись
кодом который показал GlooK, в одной из тем, мне удалось вытащить капчу, но в том коде как бы капча вытаскиваеться в файл, насколько я понял, то так, как прога многопоточная, то не хорошо создавать файлы капчи для каждого потока, а потом удалять. Т.е. мне нужно капчу в память "пихать" и делать post запрос на антигейт, но я никак не могу понять, каким образом.
Вот код GlooKa чуть поправленный под мои требования:

Код:

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], где i это номер потока.

Мои мысли по поводу Jpeg:
Мне вместо этого
Код:

BlockWrite(NewFile, hBuffer[rb], iRead - rb);
надо вставить например

Код:

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. И если можно в память картинку вставить, то как ее передать, так как на антигейт пост запрос такого вида :
Код:

multi:=Tidmultipartformdatastream.Create;
multi.AddFormField('method','post');
multi.AddFormField('key',apikey);
multi.AddFile('file',filename,ftype);

где filename- название файла?

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

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

GhostOnline 13.03.2010 10:03

Чтобы хранить картинку в памяти, юзай TMemoryStream
Передать же в антикапчу картинку можно например вот так:
multi.AddObject ('file', ftype, '',image, 'captcha.' + itype);
где:
'file' - название поля
ftype - тип картинки, например 'image/pjpeg'
image - ссылка на объект типа TMemoryStream, в котором хранится картинка
'captcha.' + itype - название файла (значения в принципе не имеет)

trigada 13.03.2010 18:23

Все норм сделал через память, но интересует еще ответ на 2-й вопрос.
Цитата:

2.Насколька я понял, то эту функцию (function fWSRecv) не могут использовать несколько потоков одновременно?
Т.е. нужно использовать критические секции для исключения одновременного доступа к файлам( или памяти) из разных потоков. Или делать Массивную память, допустим у меня все равно больше 100 потоков не будет, и под каждый поток делать какойто цикл создания памяти Jpeg[i], где i это номер потока.
Можно ли функцию использовать одновреммено в потоках, или надо ставить крит. секции, и если надо ставить их то где? Там где происходит вызов этой функции, или в самой функции, там где заносим в память картинку?

greki_hoy 13.03.2010 18:35

Цитата:

Сообщение от trigada
Все норм сделал через память, но интересует еще ответ на 2-й вопрос.


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

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

M_script_ 13.03.2010 18:55

Цитата:

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

Крит.секции не нужны.
greki_hoy, это общие фразы. Узким местом в подобном софте обычно остается скорость инета.

P.S.:
ТС, я вот только не понял, если на сокетах пишешь программу, почему работа с антигейтом через инди? :)

GhostOnline 13.03.2010 19:27

Цитата:

Сообщение от trigada
Все норм сделал через память, но интересует еще ответ на 2-й вопрос.


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

Ограничивать надо доступ к глобальной переменной
Тут же вроде обращений к глобальным переменным нет, каждый поток работает со своими переменными, следовательно
критические секции не нужны.

trigada 13.03.2010 19:29

Ясно.
Думал что неважно с инди или нет, просто на антигейте сделано так, буду делать на сокетах функцию антигейт если нужно, это что то меняет ?

M_script_ 13.03.2010 20:18

Если не важно, то зачем прогу на сокетах писать? Можно на инди.
Цитата:

Сообщение от GhostOnline
Ограничивать надо доступ к глобальной переменной

Но если потоки не меняют значение глобальной переменной, то можно не синхронизировать.


Время: 08:54