在indy的DEMO里有个ImageServer是这样的! 服务端: if sCommand = 'PIC' then begin if FileExists(ExtractFileDir(ParamStr(0)) + '\images\' + sAction) then Begin lstRequests.items.add('Serving up: ' + sAction); // open file stream to image requested fStream := TFileStream.Create(ExtractFileDir(ParamStr(0)) + '\images\' + sAction,fmOpenRead + fmShareDenyNone); // copy file stream to write stream AThread.Connection.OpenWriteBuffer; AThread.Connection.WriteStream(fStream); AThread.Connection.CloseWriteBuffer; // free the file stream FreeAndNil(fStream); lstRequests.items.add('File transfer completed'); End else AThread.Connection.WriteLn('ERR - Requested file does not exist'); AThread.Connection.Disconnect; End;客户端: with IdTCPClient do begin if connected then DisConnect; Host := edtServerHost.text; Port := StrToInt(edtServerPort.text); Connect; WriteLn('PIC:' + lstAvailableImages.Items[lstAvailableImages.itemindex]); // delete if exists // in production situation you might store binary downloads like this in a cache folder if FileExists(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex]) then DeleteFile(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex]); ftmpStream := TFileStream.Create(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex],fmCreate); while connected do ReadStream(fTmpStream,-1,true); FreeAndNil(fTmpStream); Disconnect; imgMain.Picture.LoadFromFile(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex]); end; 但他处理数据后就断开连接 如果不断开的话是不是没有办法?
Server端:
AThread.Connection.WriteInteger(ms.size); //先发送大小;
AThread.Connection.WriteStream(ms,true,true);Client端:
size := IdTCPClient1.ReadInteger; //先读取大小。
IdTCPClient1.ReadStream(ms, size , True);
AThread.Connection.WriteStream(ms,true,true);Client端:
size := IdTCPClient1.InputBuffer.Size; //先读取大小。
IdTCPClient1.ReadStream(ms, size , True);
AThread.Connection.OpenWriteBuffer;
AThread.Connection.WriteStream(ms,true,true);
AThread.FlushBuffer;
AThread.Connection.CloseWriteBuffer;Client端:
IdTCPClient1.ReadStream(ms, -1, False);酱紫……
size := IdTCPClient1.InputBuffer.Size; //先读取大小。 读出的值一直是0! 还是不行!修罗是谁?!的里面的 AThread.FlushBuffer; 我的怎么没有:(只有:AThread.Connection.FlushWriteBuffer; 试试先!不行再问
服务端:
if sCommand = 'PIC' then
begin
if FileExists(ExtractFileDir(ParamStr(0)) + '\images\' + sAction) then
Begin
lstRequests.items.add('Serving up: ' + sAction);
// open file stream to image requested
fStream := TFileStream.Create(ExtractFileDir(ParamStr(0)) + '\images\' + sAction,fmOpenRead + fmShareDenyNone);
// copy file stream to write stream
AThread.Connection.OpenWriteBuffer;
AThread.Connection.WriteStream(fStream);
AThread.Connection.CloseWriteBuffer;
// free the file stream
FreeAndNil(fStream);
lstRequests.items.add('File transfer completed');
End
else
AThread.Connection.WriteLn('ERR - Requested file does not exist');
AThread.Connection.Disconnect;
End;客户端:
with IdTCPClient do
begin
if connected then DisConnect;
Host := edtServerHost.text;
Port := StrToInt(edtServerPort.text);
Connect;
WriteLn('PIC:' + lstAvailableImages.Items[lstAvailableImages.itemindex]);
// delete if exists
// in production situation you might store binary downloads like this in a cache folder
if FileExists(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex]) then
DeleteFile(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex]);
ftmpStream := TFileStream.Create(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex],fmCreate);
while connected do
ReadStream(fTmpStream,-1,true);
FreeAndNil(fTmpStream);
Disconnect;
imgMain.Picture.LoadFromFile(ExtractFileDir(ParamStr(0)) + '\' + lstAvailableImages.Items[lstAvailableImages.itemindex]);
end;
但他处理数据后就断开连接 如果不断开的话是不是没有办法?
Client端: 要判断的。
size := IdTCPClient1.ReadInteger; //先读取大小。
if size = 0 then
begin
//释放资源.
Exit;
end;
IdTCPClient1.ReadStream(ms, size , True);
MsSize := ms.Size;
CommBlock.Command := 4003;
CommBlock.RcSize := MsSize;
AThread.Connection.WriteBuffer(CommBlock, SizeOf(CommBlock), true);
AThread.Connection.WriteStream(ms, true, true);
接收端: IdTCPClient1.ReadBuffer(CommBlock, sizeof(CommBlock));
//size:=IdTCPClient1.ReadInteger; //注意这句
size:=CommBlock.RcSize;
if size = 0 then
begin
//释放资源.
Exit;
end;
IdTCPClient1.ReadStream(ms, size , true);
这样写应该可以吧?我用的是indy9.0.14 我用WPE跟踪发现
AThread.Connection.WriteStream(ms, true, true); 这句已经发送了流的长度
于是我加了“size:=IdTCPClient1.ReadInteger; ”这句来配合他发送的长度!依旧不能结束等待:(是不是必须按 Dlwxn(流云) 的写法先
AThread.Connection.WriteInteger(ms.size);
然后接收配合
size := IdTCPClient1.ReadInteger;流云能给我个例子吗?谢谢先。
type
ARecord = packed record
Command : Integer;
Content : String[30];
end;var
CommBlock : ARecord;服务端:
procedure TForm1.IdTCPServer1Exception(AThread: TIdPeerThread;
AException: Exception);
var
ms : TMemoryStream;
begin
ms := TMemoryStream.Create;
try
CommBlock.Command := 4003;
CommBlock.Content := 'Test ReadStream';
ms.WriteBuffer(CommBlock, sizeof(CommBlock)); AThread.Connection.WriteInteger(ms.Size); //先发送大小
AThread.Connection.OpenWriteBuffer;
try
AThread.Connection.WriteStream(ms);
AThread.Connection.CloseWriteBuffer;
except
AThread.Connection.CancelWriteBuffer;
end;
finally
FreeAndNil(ms);
end;
end;客户端:用timer控件读取,Interval=500,也可以用线程。
procedure TForm1.Timer1Timer(Sender: TObject);
var
ms : TMemoryStream;
size : Integer;
begin
if not IdTCPClient1.Connected then Exit;
ms := TMemoryStream.Create;
try
size := IdTCPClient1.ReadInteger; //先读取大小。
if size = 0 then
begin
FreeAndNil(ms);
Exit;
end;
IdTCPClient1.ReadStream(ms, size, True);
ms.Position := 0;
ms.ReadBuffer(CommBlock, sizeof(CommBlock));
RichEdit1.Lines.Add(IntToStr(CommBlock.Command));
RichEdit1.Lines.Add(CommBlock.Content);
finally
FreeAndNil(ms);
end;
end;其它的设置你自己应该能够搞定,如果还不可以,留下mail我把这个例子发给你。
AThread.Connection.OpenWriteBuffer;
try
AThread.Connection.WriteStream(ms, True, True); //和上面的区别,如果这样,上面发送大小就不要了。
AThread.Connection.CloseWriteBuffer;
except
AThread.Connection.CancelWriteBuffer;
end;
finally
FreeAndNil(ms);
难道就是看他控件类型多还是所谓的设计模式用的多?
其实UDP是没有Client和Server的区别的,Indy非要搞个Client出来太书呆子了一些!