该到了要讨论TIdTCPClient和TIdTCPServer的使用了 (100分)

  • 主题发起人 主题发起人 looyo
  • 开始时间 开始时间
L

looyo

Unregistered / Unconfirmed
GUEST, unregistred user!
该到了要讨论TIdTCPClient和TIdTCPServer的使用了?
1,TIdTCPClient.readstream后台到底在完成什么样的操作,为什么我调用这个方法,始终没有完成过。

[red]TIdTCPClient.readstream要求指明读取数据块得长度,或者在服务器端得输出流得前4个字节指明数据块得长度。我得理解对不[/red]
欢迎加我一起讨论MSN&Email:Looyo@163.com
 
有什么好的理由说:该到了要讨论TIdTCPClient和TIdTCPServer的使用了?
 
我才用到这个,
支持一下
 
数据包的封装与分用
不是很好讲 你可以看一下计算机网络的教程,了解网络的7层结构(实际是5层),
这样才可以了解地层应用
 
Indy是拉圾,没什么好说的,不好用,用来做做测试还勉强
 
我正在搜集这方面的资料,哪位大虾有的话,贡献一下阿
 
http://www.delphifans.com/down_view.asp?id=624
Indy资料下载
 
楼主我目前也正在研究这方面的控件有空交流交流,
QQ:30243953
 
下面是书上的一个例子,好像并没有显式地指出stream的大小,读出的时候也没有显示地指出。不知道它的内部工作的如何进行的 。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, IdTCPConnection, IdTCPClient,
IdBaseComponent, IdComponent, IdTCPServer;

type
TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
IdTCPClient1: TIdTCPClient;
Image1: TImage;
Image2: TImage;
BitBtn1: TBitBtn;
Bevel1: TBevel;
Bevel3: TBevel;
Bevel4: TBevel;
procedure BitBtn1Click(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
var
Temp:TMemoryStream;
begin
Temp:=TMemoryStream.Create;
//将图像文件保存到内存流
Image1.Picture.Graphic.SaveToStream(Temp);
//发送图像信息
IdTCPClient1.Connect();
IdTCPClient1.writestream(Temp);
IdTCPClient1.Disconnect();
Temp.Free ;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
const
TempImageFile='c:/test.bmp';
//设置的临时图像文件
var
t:TMemoryStream;
begin
t:=TMemoryStream.Create;
AThread.Connection.ReadStream(t,-1,True);
//从连接中取得流式数据
t.SaveToFile(TempImageFile);
Image2.Picture.LoadFromFile(TempImageFile);
t.Free ;
end;

end.
 
to kkkchenA
是不是INDY的服务器组件,在输出数据流前面会自动加上长度啊
 
下面是readStream的代码。looyo你说得对,当AByteCount是-1的时候,数据的大小它自动处理了,直到所有的数据读完,或者是断开。

procedure TIdTCPConnection.ReadStream(AStream: TStream; AByteCount: Integer = -1;
const AReadUntilDisconnect: Boolean = False);
var
i: Integer;
LBuf: packed array of Byte;
LBufSize: Integer;
LWorkCount: Integer;

procedure AdjustStreamSize(AStream: TStream; const ASize: integer);
var
LStreamPos: LongInt;
begin
LStreamPos := AStream.Position;
AStream.Size := ASize;
// Must reset to original size as in some cases size changes position
if AStream.Position <> LStreamPos then begin
AStream.Position := LStreamPos;
end;
end;

begin
if (AByteCount = -1) and (AReadUntilDisconnect = False) then begin
// Read size from connection
AByteCount := ReadInteger;
end;
// Presize stream if we know the size - this reduces memory/disk allocations to one time
if AByteCount > -1 then begin
AdjustStreamSize(AStream, AStream.Position + AByteCount);
end;

if AReadUntilDisconnect then begin
LWorkCount := High(LWorkCount);
BeginWork(wmRead);
end else begin
LWorkCount := AByteCount;
BeginWork(wmRead, LWorkCount);
end;

try
// If data already exists in the buffer, write it out first.
if InputBuffer.Size > 0 then begin
i := Min(InputBuffer.Size, LWorkCount);
InputBuffer.Position := 0;
AStream.CopyFrom(InputBuffer, i);
InputBuffer.Remove(i);
Dec(LWorkCount, i);
end;

LBufSize := Min(LWorkCount, RecvBufferSize);
SetLength(LBuf, LBufSize);

while Connected and (LWorkCount > 0) do begin
i := Min(LWorkCount, LBufSize);
//TODO: Improve this - dont like the use of the exception handler
//DONE -oAPR: Dont use a string, use a memory buffer or better yet the buffer itself.
try
try
ReadBuffer(LBuf[0], i);
except
on E: EIdConnClosedGracefully do begin
if AReadUntilDisconnect then begin
i := InputBuffer.Size;
Move(InputBuffer.Memory^, LBuf[0], i);
InputBuffer.Clear; //InputBuffer.Remove(InputBuffer.Size);
end else begin
i := 0;
raise;
end;
end;
end;
finally
if i > 0 then begin
AStream.WriteBuffer(LBuf[0], i);
Dec(LWorkCount, i);
end;
end;
end;
finally
EndWork(wmRead);
if AStream.Size > AStream.Position then begin
AStream.Size := AStream.Position;
end;
LBuf := NIL;
end;
end;
 
当时我要问的是服务器端用别的语言写的时候,是不是要自己去在开始的地方标上长度
 
呵呵!这里真是高手云集:)
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2575637
 
后退
顶部