我用下面语句老出错,这是为何呀?
var
rbyte:array [1..4096] of rbyte;
begin
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
...
end;
提示错误是:
[Error] mclient.pas(56): E2033 Types of actual and formal var parameters must be identical我试着:
type
TBytes=array of byte;
var
rbyte:TBytes;
begin
setLength(rbyte,4096);
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
..
end;
还是报错,这是为何呀?我用的是delphi2005中带的indy10
还请大侠们指点!谢谢!
var
rbyte:array [1..4096] of rbyte;
begin
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
...
end;
提示错误是:
[Error] mclient.pas(56): E2033 Types of actual and formal var parameters must be identical我试着:
type
TBytes=array of byte;
var
rbyte:TBytes;
begin
setLength(rbyte,4096);
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
..
end;
还是报错,这是为何呀?我用的是delphi2005中带的indy10
还请大侠们指点!谢谢!
解决方案 »
- FastReport 3.0如何把两个adoquery 中数据打印出来
- 请问谁有 Installshield express 的学习资料啊?
- 焦点保存问题
- 如何实现任意程度倾斜的斜体字(不是文字的角度)?谢。
- DELPHI编程操作远程注册表问题,参与就有份!
- 想装个GIFImage控件,但里面没有.dpk文件,请问该怎么装?(delphi7)
- 我看过好多软件里面都使用 STRINGGRID 控件,如何实现点击 fixedrow 时,可以进行排序?
- <<<<<请看不错的笑话
- delphi记录删除
- 求delphi5升级包及ado升级包的序列号!
- dbgrid滚动条的问题
- sqlserver数据库连接错误!原因:数据库服务器用的SQLSERVER方式登录,客户端机器用的机器名称(中文),登录时错误。
lcBytes: Integer;
...
begin
...
lcBytes:= 4096;
IdTCPClient1.Socket.ReadBytes(rbyte, lcBytes);
...
end;可能采用的引用传递,而不是值传递的原因!
如下:uses IdGlobalvar
rbyte:TBytes;begin IdTCPClient1.Socket.ReadBytes(rbyte, 4096);
高手高手!是的,我将IdGlobal加上去,是没有再报错了!
大侠,我还想请教您一个问题,我想做一个传送文件的程序,一个服务端,一个客户端,服务端发送文件,客户端接收文件,下面是一部分代码,不知这样写对不对,还请指点:
服务器端:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
AContext.Connection.IOHandler.WriteLn('Connected succeed');
AContext.Connection.IOHandler.WriteFile('e:\aa.rar');
end;客户端:
procedure TForm1.Button1Click(Sender: TObject);
var
pos,FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
begin
Try
IdTCPClient1.Connect;
except
showmessage('连接失败!');
exit;
end;
......
pos:=4096;
sFile:=TFileStream.Create('e:\bb.rar',fmCreate);
While pos<Filesize do
begin
IdTCPClient1.Socket.ReadBytes(rbyte,pos);
sFile.Write(rByte,4096);
inc(pos,4096);
end;
end;
是连接到服务器,服务器就自动写一个文件到你的客户端。
你的接收代码逻辑也有点问题,rar文件可能写得不对。
While pos<Filesize do
begin
IdTCPClient1.Socket.ReadBytes(rbyte,pos);
sFile.Write(rByte,4096);
inc(pos,4096);
end;
最后一包如果小于4096,你仍然会写4096个字节到文件中,造成文件错误。你的客户端的读文件代码应该写在TcpClient的OnWork事件中。
procedure TForm1.IdTCPClient1Work(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Integer);
begin
......
end;
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
这条语句时,rbyte的所含的内容一直不变,readbytes取的内容一直是开始的4096字节的内容。
它不会取后面的内容。这是怎么回事?还请指点!
我想利用流先将文件打开,再按4096字节进行读取,用server端的iohandler写入,但我不清楚server端iohandler用哪个方法进行写?
客户端
procedure TForm1.Button1Click(Sender: TObject);
var
pos,FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
begin
Try
IdTCPClient1.Connect;
except
showmessage('连接失败!');
exit;
end;
end;procedure TForm1.IdTCPClient1Work(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Integer);
var
pos,FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
begin
pos:=0;
FileSize:=StrToInt(IdTCPClient1.IOHandler.ReadLn);
Showmessage(inttostr(filesize));
sFile:=TFileStream.Create('e:\bb.doc',fmCreate);
While pos<Filesize do
begin
IdTCPClient1.IOHandler.ReadBytes(rbyte,AWorkCount);
sFile.Write(rByte,4096);
inc(pos,4096);
end;
FreeAndNil(sFile);
end;服务器端:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
sFile:TFileStream;
begin
sFile:=TFileStream.Create('e:\aa.doc',FmopenRead);
AContext.Connection.IOHandler.WriteLn(IntToStr(sFile.Size));
showmessage(intTostr(sFile.Size));
FreeAndNil(sFile);
AContext.Connection.IOHandler.WriteFile('e:\aa.doc');
end;
或者用IOHandler.Write(....),也可以写入。
客户端:
procedure TForm1.Button1Click(Sender: TObject);
var
FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
begin
Try
IdTCPClient1.Connect;
except
showmessage('连接失败!');
exit;
end;
......
FileSize:=StrToInt(IdTCPClient1.IOHandler.ReadLn);
sFile:=TFileStream.Create('e:\bb.rar',fmCreate);
While FileSize>4096 do
begin
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
sFile.Write(rByte,4096);
inc(iFileSize,-4096);
end;
IdTCPClient1.Socket.ReadBytes(rbyte,iFileSize);
sFile.Write(rByte,iFileSize);
sFile.Free;
end;服务端:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
sFile:TFileStream;
begin
sFile:=TFileStream.Create('e:\aa.doc',FmopenRead);
AContext.Connection.IOHandler.WriteLn(IntToStr(sFile.Size));
// showmessage(intTostr(sFile.Size));
FreeAndNil(sFile);
AContext.Connection.IOHandler.WriteFile('e:\aa.doc');
end;
但这样还是不行,这样只是解决了文件大小问题,但是文件的内容全部变了,并且我在跟踪rbyte这个变量时,发现它的内容在while循环里面一直都是开始4096字节的内容,没有变化。
好像ReadBytes这个方法只读取了开始的4096个字节的内容,后面的内容没有读取,是否还要在readbytes方法后面还要加上缓冲区移动指针的方法?但这如何做呢?还请您指点一下!谢谢!
IdTCPClient1.ReadBuffer(rbyte,4096);
是没问题的。都能读出来。传输也正常。
建议Indy9.0.18的好http://lysoft.7u7.net
Setlength(rbyte,4096);?
由于IdTCPServerExecute方法在某一线程上下文中执行,因此显示数据和添加事件记录都是将相应的方法传递给Synchronize调用来完成的。/////////////////////////找不到问题,既然读第一包是好的,后面也应该没问题。
装个indy9吧,保证没问题。 我的D2005的Indy10用都不能用。
VBuffer is the variable argument used to store values read from the data source for the IOHandler connection.AByteCount indicates the number of byte values expected for the read request. When AByteCount contains 0 (zero), no data is read from the data source for the IOHandler. when AByteCount contains -1, data is read from the data source until it is disconnected or the ReadTimeout value has elapsed.ReadBytes reads data from the IOHandler data source until the number of bytes in AByteCount has been accumulated in InputBuffer, or CheckForDisconnect interrupts the read request.On successful completion of the read request, values are extracted from InputBuffer into VBuffer.AAppend indicates that values extracted from the input buffer should be appended to existing data in VBuffer. When AAppend is False, any values in VBuffer are discarded during extraction of data from InputBuffer.这是indy10帮助文件对readbytes方法的解释,有些不大理解
IdTCPClient1.IOHandler.ReadLn
或
IdTCPClient1.IOHandler.ReadString()看看对不对。
aa.txt文件里面只有一个字符a
我对客户端程序进行调试,发现在语句执行后
IdTCPClient1.Socket.ReadBytes(rbyte,FileSize);
rbyte内容是84,0,0,0.....
前面对rbyte分配的内存空间。setlength(rbyte,4096)
怎么第一个字符是84呢?应该是61呀,
而执行完sFile.Write(rByte,iFileSize);后,我用Ultraedit打开这两个文件aa.txt,bb.txt
用HEX查看,
发现aa.txt显示内容为:61
bb.txt显示内容为:F0真是晕倒!这是怎么回事?越来越糊涂了!
rbyte:array [1..4096] of rbyte;
begin
IdTCPClient1.Socket.ReadBytes(@rbyte[1],4096);
...
end;
rbyte:Tbytes;
sFile:TFileStream;
begin
rbyte:=@bytes[0];
.....
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
.....
IdTCPClient1.Socket.ReadBytes(rbyte,4096);
rbyte的内容和 服务器端的内容就不对了!
用telnet测试,启动运行-》telnet
>open>127.0.0.1 88888 (ip和端口号)看看能不能看到服务端发送的文本文件。
IdTCPClient1.IOHandler.ReadString
IdTCPClient1.IOHandler.ReadStream
不是
IdTCPClient1.Socket.ReadString
并且readstream方法是这样定义的:
procedure ReadStream(AStream: TIdStreamVCL, AByteCount: LongInt = -1, AReadUntilDisconnect: Boolean = False); virtual;
AByteCount和AReadUnitDisconnect可以省略。
客户端我改成:
procedure TForm1.Button1Click(Sender: TObject);
var
FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
bytes:array [0..4095] of byte;
cFile:TIdStreamVCL;
begin
rbyte:=@bytes;
Try
IdTCPClient1.Connect
except
showmessage('连接失败!');
exit;
end;
sFile:=TFileStream.Create('e:\bb.txt',fmCreate);
cFile:=TIdStreamVCL.Create(sFile,true);
IdTCPClient1.IOHandler.ReadStream(cFile);end;执行到IdTCPClient1.IOHandler.ReadStream(cFile);程序就不响应了,并且Delphi2005也不响应了。只有调了任务管理器将这二个程序终止,但服务器端还是正常运行!
我试着这样写:
procedure TForm1.Button1Click(Sender: TObject);
var
FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
bytes:array [0..4095] of byte;
cFile:TIdStreamVCL;
begin
rbyte:=@bytes;
Try
IdTCPClient1.Connect
except
showmessage('连接失败!');
exit;
end;
FileSize:=StrToInt(IdTCPClient1.IOHandler.ReadLn);
sFile:=TFileStream.Create('e:\bb.txt',fmCreate);
cFile:=TIdStreamVCL.Create(sFile,true);
While Filesize>4096 do
begin
cFile.VCLStream.Read(bytes,4096);
inc(FileSize,-4096);
end;
cFile.VCLStream.Read(bytes,Filesize);
end;程序运行没问题,但是bb.txt这个文件长度为0,什么内容都没有。
而我用telnet看到服务端发送内容为a1,1是文件长度,a是文件内容
var
FileSize:integer;
rbyte:Tbytes;
sFile:TFileStream;
bytes:array [0..4095] of byte;
cFile:TIdStreamVCL;
begin
Try
IdTCPClient1.Connect
except
showmessage('连接失败!');
exit;
end;
FileSize:=StrToInt(IdTCPClient1.IOHandler.ReadLn);
sFile:=TFileStream.Create('e:\bb.txt',fmCreate);
cFile:=TIdStreamVCL.Create(sFile);
IdTCPClient1.IOHandler.InputBufferToStream(cFile,filesize);
end;我开始测试时用的是一个1k大小文件,执行完后,文件接收正常,但我用大些文件,如63K,在执行时就会报:"Not enough data in buffer",这是怎么回事呢?
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
sFile:TFileStream;
sv:TIdStreamVCL;
begin
sFile:=TFileStream.Create('e:\fmLogin.pas',FmopenRead);
AContext.Connection.IOHandler.WriteLn(IntToStr(sFile.Size));
sv:=TIdStreamVCL.Create(sFile,true);
AContext.Connection.IOHandler.Write(sv,sFile.Size);
FreeAndNil(sFile);
end;客户端:procedure TForm1.Button1Click(Sender: TObject);
var
FileSize:integer;
sFile:TFileStream;
sv:TIdStreamVCL;
begin
Try
IdTCPClient1.Connect;
except
showmessage('连接失败!');
exit;
end; FileSize:=StrToInt(IdTCPClient1.IOHandler.ReadLn);
sFile:=TFileStream.Create('e:\bb.pas',fmCreate);
sv:=TIdStreamVCL.Create(sFile,true); While FileSize>4096 do
begin
IdTCPClient1.IOHandler.ReadStream(sv,4096);
inc(FileSize,-4096);
end;
IdTCPClient1.IOHandler.ReadStream(sv,FileSize);
sFile.Free;
end;
大侠,再请问您一下,像上面的代码,当服务器端传送了文件大小后,是整数型,再接着传送文件,我用telnet来接收时,发现文件大小和文件内容重复传送,客户端在接收时是否是根据read的各种函数来接收服务器端发过来的数据?如:文件大小,客户端是用readln()来接收到,如果用readstream()来接收,那就会报错了。
而文件内容是利用流来发送的,则客户端也要用readstream()函数来读取了.是这样理解吗?
对Indy的理解不是很深,不知道处理机制是怎么样的。