1

What's the best way to go about sending a TMemoryStream through Indy?

At the moment I'm trying:

procedure TClientForm.IdTCPClient1Connected(Sender: TObject);
begin
  IdTCPClient1.IOHandler.Write(KStore.Size);
  KStore.Position := 0;
  IdTCPClient1.IOHandler.Write(KStore);

  Memo1.Lines.Add('Client connected with server');
end

And at the Server end:

function MemoryStreamToString(M: TMemoryStream): string;
begin
  SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char));
end;

procedure TClientForm.IdTCPServer1Connect(AContext: TIdContext);
var
  LStore: TMemoryStream;
  Size: Int64;
  LStore := TMemoryStream.Create;
  LStore.Position := 0;
  Size := AContext.Connection.IOHandler.ReadInt64();
  AContext.Connection.IOHandler.ReadStream(LStore,Size);
end;

But despite a lack of errors, at the other end using that memory stream to string function just returns ???????????????????? in the text file I'm saving it to.

4

1 回答 1

3

TIdIOHandler.Write(TStream)TIdIOHandler.ReadStream()可以为您处理财产的传输和接收TMemoryStream.Size,例如:

procedure TClientForm.IdTCPClient1Connected(Sender: TObject); 
begin 
  IdTCPClient1.IOHandler.LargeStream := True; 
  IdTCPClient1.IOHandler.Write(KStore, 0, True); 
  Memo1.Lines.Add('Client connected with server'); 
end;

.

function MemoryStreamToString(M: TMemoryStream): string; 
begin 
  SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char)); 
end; 

procedure TClientForm.IdTCPServer1Connect(AContext: TIdContext); 
var 
  LStore: TMemoryStream; 
  S: String;
begin
  LStore := TMemoryStream.Create; 
  try
    AContext.Connection.IOHandler.LargeStream := True; 
    AContext.Connection.IOHandler.ReadStream(LStore, -1, False); 
    S := MemoryStreamToString(LStore); 
  finally
    LStore.Free;
  end;
end;

话虽如此,您提到错误与从 to 的转换TMemoryStream有关StringTMemoryStream请显示两端的实际内容。内容可能不是您所期望的。当您将 a 存储到 中时,客户端TMemoryStream包含'?'以开头的字符,或者客户端未将编码字符发送到服务器。StringTMemoryStreamUTF-16

于 2012-04-12T20:00:30.373 回答