:)
我又来了...现在我正在尝试玩流。我的目标是使用 TCPServer 向 TCPClient 请求流并正确接收它。这是我正在尝试但没有成功的:
procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
var
SCmd: string;
Client: TClient;
LQueue: TStringList;
WQueue: TStringList;
Stream: TMemoryStream;
begin
Client := TClient(AContext.Data);
// Send Cmd
LQueue := nil;
try
WQueue := Client.QMsg.Lock;
try
if (WQueue.Count > 0) then
begin
LQueue := TStringList.Create;
LQueue.Assign(WQueue);
WQueue.Clear;
end;
finally
Client.QMsg.Unlock;
end;
if (LQueue <> nil) then
begin
SCmd := LQueue[0];
AContext.Connection.IOHandler.Write(SCmd);
end;
finally
LQueue.Free;
end;
// Receive Data
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
if not AContext.Connection.IOHandler.CheckForDataOnSource(100) then Exit;
AContext.Connection.IOHandler.CheckForDisconnect;
end;
if (SCmd = 'sendfile') then
begin
Stream := TMemoryStream.Create;
try
AContext.Connection.IOHandler.ReadStream(Stream, -1);
Stream.Position := 0;
Stream.SaveToFile(ExtractFilePath(Application.ExeName) + 'test.zip');
finally
Stream.Free;
end;
end;
end;
在客户端,我创建了一个用于侦听和处理命令的线程。这是代码:
procedure TClientProc.Execute;
begin
TCPClient := TIdTCPClient.Create(nil);
while (not Terminated) do
begin
with TCPClient do
begin
if (Connected) then
try
FCmd := Trim(IOHandler.ReadLn);
if (FCmd <> '') then Synchronize(CommandProc);
except
end else
begin
if (FCnt >= FInt) then
try
ConnectTimeout := 4000;
Port := StrToInt(FPort);
Host := FHost;
Connect;
except
FCnt := 0;
end else
begin
Inc(FCnt);
end;
end;
Sleep(1000);
end;
end;
TCPClient.Disconnect;
TCPClient.Free;
end;
Procedure TClientProc.CommandProc;
var
Stream: TMemoryStream;
begin
if FCmd = 'sendfile' then
begin
Stream := TMemoryStream.Create;
try
Stream.LoadFromFile(ExtractFilePath(Application.ExeName) + 'test.zip');
Stream.Position := 0;
TCPClient.IOHandler.Write(Stream, 0, True);
finally
Stream.Free;
end;
end;
end;
拜托,我做错了什么?
顺便说一句,新年快乐!!
在服务器端,如果在TClient
的队列中有多个命令,OnExecute
有机会检查它时,您将丢弃除第一个命令之外的所有命令。 您需要处理所有这些。
尝试更多类似的东西:
procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
var
SCmd: string;
Client: TClient;
WQueue: TStringList;
Stream: TMemoryStream;
begin
Client := TClient(AContext.Data);
// Send Cmd
WQueue := Client.QMsg.Lock;
try
if (WQueue.Count > 0) then
begin
SCmd := WQueue[0];
WQueue.Delete(0);
end;
finally
Client.QMsg.Unlock;
end;
if (SCmd = '') then
begin
AContext.Connection.IOHandler.Write(SCmd);
if (SCmd = 'sendfile') then
begin
Stream := TMemoryStream.Create;
try
AContext.Connection.IOHandler.ReadStream(Stream, -1);
Stream.Position := 0;
Stream.SaveToFile(ExtractFilePath(Application.ExeName) + 'test.zip');
finally
Stream.Free;
end;
end;
end;
end;
当然,这仅在服务器是发送命令的唯一一方时才有效。 如果客户端向服务器发送命令,这将使代码更难管理,并且需要更详细的协议,因为服务器需要能够区分入站数据何时属于命令和响应。