关于动态idhttp在多线程中异常终止的问题,请高手帮忙,谢谢!---已经快24小时了,大家多多帮忙啊! ( 积分: 70 )

  • 主题发起人 主题发起人 weserver
  • 开始时间 开始时间
W

weserver

Unregistered / Unconfirmed
GUEST, unregistred user!
最近小弟学习多线程,模仿做了一个测试的多线程密码扫描软件,不过奇怪的是,软件扫到几个密码后,线程就显示终止了,不知道是为什么???

以下是一些主要的代码,请高手帮忙看一下,并多多指导,谢谢!
主程序
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Scanner, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdHTTP;

type
TForm1 = class(TForm)
cmdstart: TButton;
cmdstop: TButton;
Memo1: TMemo;
Label1: TLabel;
TxtMin: TEdit;
Label2: TLabel;
TxtMax: TEdit;
IdHTTP1: TIdHTTP;
procedure cmdstopClick(Sender: TObject);
procedure cmdstartClick(Sender: TObject);
procedure WMThreadDone(var Msg:TMessage); message WM_THREADDONEMSG;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
SocketMonkeys:Array[0..MAX_THREADS-1] of ScannerThread;
ThreadsActive:integer;
CurrEndnum,Currnum,Startnum,Endnum:integer;
implementation

{$R *.dfm}
procedure TForm1.WMThreadDone(var Msg:TMessage);
var
DeadThread:Integer;
begin
Dec(ThreadsActive);
DeadThread:=Msg.Wparam; //the ID of the thread that just completed
SocketMonkeys[DeadThread]:=nil;
if ThreadsActive=0 then
memo1.Lines.Add('密码测试完成');
if CMDStop.Enabled then //We haven't been stopped yet
begin
SocketMonkeys[DeadThread]:=ScannerThread.Create(DeadThread,Handle,Currnum,CurrEndnum);
Inc(ThreadsActive);
Currnum:=CurrEndnum+1;
CurrEndnum:=CurrEndnum+10;
if CurrEndnum > Endnum then
begin
CurrEndnum:=Endnum;
CMDStop.Enabled:=false;
cmdstart.Enabled:=true;
end;
end;

Application.ProcessMessages;

end;

procedure TForm1.cmdstopClick(Sender: TObject);
var
i:integer;
begin
cmdstart.Enabled := True;
cmdstop.Enabled := False;

for i:=0 to MAX_THREADS-1 do
SocketMonkeys.Terminate;
end;

procedure TForm1.cmdstartClick(Sender: TObject);
var
i:integer;
begin
memo1.Lines.Clear;
cmdStart.Enabled := false;
cmdstop.Enabled := true;

Caption:='扫描中....';

Startnum:=StrToInt(TxtMin.Text);
Endnum:=StrToInt(TxtMax.Text);
Currnum:=Startnum;
CurrEndnum:=Startnum+10;

if CurrEndnum > Endnum then
CurrEndnum:=Endnum;

for i:=0 to MAX_THREADS-1 do
begin
SocketMonkeys:=ScannerThread.Create(i,Handle,Currnum,CurrEndnum);
inc(ThreadsActive);

Currnum:=CurrEndnum+1;
CurrEndnum:=CurrEndnum+10;
if CurrEndnum > Endnum then
CurrEndnum:=Endnum;

if Currnum >= Endnum then
break;
end;
end;

end.




扫描线程
unit Scanner;

interface

uses
Windows, Messages, Classes,SysUtils,WinInet,Idhttp;
const
MAX_THREADS = 6;



WM_THREADDONEMSG=WM_USER+99;
WM_PORTSTATUS=WM_USER+100;
type
ScannerThread = class(TThread)
private
FWnd: HWND;
FID:Integer;
Fnum:Integer;
Enum:Integer;
Params: TStrings;
htmlstr,showdlg,str1,str2,sFnum1:string;
procedure Testnum;
procedure rmemo;
procedure ThreadTerminate(Sender: TObject);
protected
procedure Execute; override;
public
constructor Create(ID:Integer;Wnd:HWND;Startnum,Endnum:integer);
destructor Destroy; override;
end;

implementation
uses unit1;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure ScannerThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ ScannerThread }
constructor ScannerThread.Create(ID:Integer;Wnd:HWND;Startnum,Endnum:integer);
begin
inherited Create(True);
FreeOnTerminate:=true;
OnTerminate:=ThreadTerminate;

FID:=ID;
FWnd:=Wnd;
Enum:=Endnum;

Fnum:=Startnum;
Resume;
end;

destructor ScannerThread.Destroy;
begin
inherited destroy;
end;

procedure ScannerThread.Testnum;
const
password = '123456';
x = '33';
y = '44';
var
sFnum,strget:string;
IdHTTP:TIdHTTP;
begin
IdHTTP := TIdHTTP.Create(nil);
try
begin
sFnum:=inttostr(Fnum);
sFnum1:='hzxs'+sFnum;
htmlstr:='';
strget:='http://***.***.***';
htmlstr:=IdHttp.get(strget);
end;
except
Terminate; //Something else went wrong - kill the thread
IdHttp.Free;
end;

if Terminated then
Exit;
end;

procedure ScannerThread.rmemo;
begin
form1.Memo1.Lines.Add(sFnum1);
end;

procedure ScannerThread.Execute;
begin
while not Terminated do
begin
Testnum;
if pos(sFnum1,htmlstr)>0 then
Synchronize(rmemo);
Fnum:=Fnum +1;
if Fnum > Enum then
Terminate;
end;
end;

procedure ScannerThread.ThreadTerminate(Sender: TObject);
begin
PostMessage(FWnd,WM_THREADDONEMSG,FID,0);
end;


end.


大家多多帮忙哦,谢谢啦
 
最近小弟学习多线程,模仿做了一个测试的多线程密码扫描软件,不过奇怪的是,软件扫到几个密码后,线程就显示终止了,不知道是为什么???

以下是一些主要的代码,请高手帮忙看一下,并多多指导,谢谢!
主程序
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Scanner, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdHTTP;

type
TForm1 = class(TForm)
cmdstart: TButton;
cmdstop: TButton;
Memo1: TMemo;
Label1: TLabel;
TxtMin: TEdit;
Label2: TLabel;
TxtMax: TEdit;
IdHTTP1: TIdHTTP;
procedure cmdstopClick(Sender: TObject);
procedure cmdstartClick(Sender: TObject);
procedure WMThreadDone(var Msg:TMessage); message WM_THREADDONEMSG;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
SocketMonkeys:Array[0..MAX_THREADS-1] of ScannerThread;
ThreadsActive:integer;
CurrEndnum,Currnum,Startnum,Endnum:integer;
implementation

{$R *.dfm}
procedure TForm1.WMThreadDone(var Msg:TMessage);
var
DeadThread:Integer;
begin
Dec(ThreadsActive);
DeadThread:=Msg.Wparam; //the ID of the thread that just completed
SocketMonkeys[DeadThread]:=nil;
if ThreadsActive=0 then
memo1.Lines.Add('密码测试完成');
if CMDStop.Enabled then //We haven't been stopped yet
begin
SocketMonkeys[DeadThread]:=ScannerThread.Create(DeadThread,Handle,Currnum,CurrEndnum);
Inc(ThreadsActive);
Currnum:=CurrEndnum+1;
CurrEndnum:=CurrEndnum+10;
if CurrEndnum > Endnum then
begin
CurrEndnum:=Endnum;
CMDStop.Enabled:=false;
cmdstart.Enabled:=true;
end;
end;

Application.ProcessMessages;

end;

procedure TForm1.cmdstopClick(Sender: TObject);
var
i:integer;
begin
cmdstart.Enabled := True;
cmdstop.Enabled := False;

for i:=0 to MAX_THREADS-1 do
SocketMonkeys.Terminate;
end;

procedure TForm1.cmdstartClick(Sender: TObject);
var
i:integer;
begin
memo1.Lines.Clear;
cmdStart.Enabled := false;
cmdstop.Enabled := true;

Caption:='扫描中....';

Startnum:=StrToInt(TxtMin.Text);
Endnum:=StrToInt(TxtMax.Text);
Currnum:=Startnum;
CurrEndnum:=Startnum+10;

if CurrEndnum > Endnum then
CurrEndnum:=Endnum;

for i:=0 to MAX_THREADS-1 do
begin
SocketMonkeys:=ScannerThread.Create(i,Handle,Currnum,CurrEndnum);
inc(ThreadsActive);

Currnum:=CurrEndnum+1;
CurrEndnum:=CurrEndnum+10;
if CurrEndnum > Endnum then
CurrEndnum:=Endnum;

if Currnum >= Endnum then
break;
end;
end;

end.




扫描线程
unit Scanner;

interface

uses
Windows, Messages, Classes,SysUtils,WinInet,Idhttp;
const
MAX_THREADS = 6;



WM_THREADDONEMSG=WM_USER+99;
WM_PORTSTATUS=WM_USER+100;
type
ScannerThread = class(TThread)
private
FWnd: HWND;
FID:Integer;
Fnum:Integer;
Enum:Integer;
Params: TStrings;
htmlstr,showdlg,str1,str2,sFnum1:string;
procedure Testnum;
procedure rmemo;
procedure ThreadTerminate(Sender: TObject);
protected
procedure Execute; override;
public
constructor Create(ID:Integer;Wnd:HWND;Startnum,Endnum:integer);
destructor Destroy; override;
end;

implementation
uses unit1;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure ScannerThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ ScannerThread }
constructor ScannerThread.Create(ID:Integer;Wnd:HWND;Startnum,Endnum:integer);
begin
inherited Create(True);
FreeOnTerminate:=true;
OnTerminate:=ThreadTerminate;

FID:=ID;
FWnd:=Wnd;
Enum:=Endnum;

Fnum:=Startnum;
Resume;
end;

destructor ScannerThread.Destroy;
begin
inherited destroy;
end;

procedure ScannerThread.Testnum;
const
password = '123456';
x = '33';
y = '44';
var
sFnum,strget:string;
IdHTTP:TIdHTTP;
begin
IdHTTP := TIdHTTP.Create(nil);
try
begin
sFnum:=inttostr(Fnum);
sFnum1:='hzxs'+sFnum;
htmlstr:='';
strget:='http://***.***.***';
htmlstr:=IdHttp.get(strget);
end;
except
Terminate; //Something else went wrong - kill the thread
IdHttp.Free;
end;

if Terminated then
Exit;
end;

procedure ScannerThread.rmemo;
begin
form1.Memo1.Lines.Add(sFnum1);
end;

procedure ScannerThread.Execute;
begin
while not Terminated do
begin
Testnum;
if pos(sFnum1,htmlstr)>0 then
Synchronize(rmemo);
Fnum:=Fnum +1;
if Fnum > Enum then
Terminate;
end;
end;

procedure ScannerThread.ThreadTerminate(Sender: TObject);
begin
PostMessage(FWnd,WM_THREADDONEMSG,FID,0);
end;


end.


大家多多帮忙哦,谢谢啦
 
兄弟我劝你不要用它了, 我改了2个晚上, 搞定这个多线程下不死了,可是速度慢了,又死了

又搞了速度慢不死,结果重定向时又死了, 呵呵,里面代码太烂了

改了 Http中的Bug 发现 idTcp 中又有Bug,改完,发现那个线程类又有问题, 线程同步又有
问题

改着着就不想改了,


用 Wininet.dll(internetopen 等) 中的几个函数来得简单,稳定 但是速度慢

自己实现http也有点麻烦

有好方法告诉我一下
 
多线程多个Idhttp实例下时 Indy的idtcp中有一个 连接线程,会抛出异常,并且这个异常没有处理,(这种情况好多个地方都有, 只要异常多,就会经常死)
 
谢谢楼上的两位,不知道下面哪位兄弟有好的方法可供参考一下...
 
我昨天也在试,也发现如果异常处理的好,可能死的时间就慢一点,如果处理不好,就可能很快死....我也感觉是抛出异常在做怪
 
我们合伙实现一个 http客户端如何,肯定比这些垃圾好
 
像 indy这些开源的控件,过分注重设计,
 
 而忽略了软件最重要的东西,特别是通迅软件, 稳定,简单,高效

 很简单的东西它也搞上几个类,一层套一层
 
小弟基础不是很好,哪位仁兄能指点一二....
 
今天搞了一天, 把一个 unix下的下载程序改到windows下了,
速度是 auhttp 和 idhttp 和 5倍以上,

等我把它搞稳定了,给大家用 还要用 delphi 封装一层, dll是 c
 
期待中....
 
我写出来了,试试
论坛中能否传 dll
 
可以发到我的email中吗??谢谢...最好有相关的使用参考代码
我的email: info@weserver.com
 
后退
顶部