简体   繁体   中英

Delphi idtcpserver idtcpclient tstringstream to string

I try to send a string from a tidtcpserver to a tidtcpclient in Delphi, but when i send a string the client receives nothing. I don't get any errors. I am using tstringstream because i want to send a base64 string(writeln/readln can't send/receive that much text) This is the send code in idtcpserver1:

procedure TForm1.sendtext(index:integer; txt:string);
var
  StrStream:tStream;
  List: TList;
  AContext: TIdContext;
begin
  txt := trim(txt);
  strstream := TMemoryStream.Create;
  strstream.Write(PAnsiChar(txt)^, Length(txt));
  strstream.Position := 0;
  List := idTcpServer1.Contexts.LockList;
  AContext := TIdContext(List[index]);
  AContext.Connection.IOHandler.write(StrStream);
  idTcpServer1.Contexts.UnLockList;
end;

This is the read code in idtcpclient1

procedure TIndyClient.Execute;
var
StrStream:tStringStream;
receivedtext:string;
begin
StrStream := tstringstream.Create;
form1.IdTCPClient1.IOHandler.readstream(StrStream);
receivedtext := strstream.DataString;
if receivedtext = '' = false then
begin
  showmessage(receivedtext);
end;
end;

Does anyone know what i am doing wrong?

You are making a very common newbie mistake of mismatching the IOHandler.Write(TStream) and IOHandler.ReadStream() calls. By default, ReadStream() expects the stream data to be preceded by the stream size, but Write(TStream) does not send the stream size by default.

Try this instead:

procedure TForm1.sendtext(index: integer; const txt: string);
var
  StrStream: TMemoryStream;
  List: TList;
  AContext: TIdContext;
begin
  strStream := TMemoryStream.Create;
  try
    WriteStringToStream(StrStream, Trim(txt), enUTF8);
    List := idTcpServer1.Contexts.LockList;
    try
      AContext := TIdContext(List[index]);
      AContext.Connection.IOHandler.Write(StrStream, 0, True);
    finally
      idTcpServer1.Contexts.UnlockList;
    end;
  finally
    StrStream.Free;
  end;
end;

procedure TIndyClient.Execute;
var
  StrStream: TMemoryStream;
  receivedtext: string;
begin
  StrStream := TMemoryStream.Create;
  try
    Form1.IdTCPClient1.IOHandler.ReadStream(StrStream, -1, False);
    StrStream.Position := 0;
    receivedtext := ReadStringFromStream(StrStream, enUTF8);
  finally
    StrStream.Free;
  end;
  if receivedtext <> '' then
  begin
    // ShowMessage() is not thread-safe...
    MessageBox(0, PChar(receivedtext), PChar(Application.Title), MB_OK);
  end;
end;

Alternatively, because the stream size is now being sent, the receiving code can use ReadString() instead of ReadStream() :

procedure TIndyClient.Execute;
var
  receivedtext: string;
begin
  with Form1.IdTCPClient1.IOHandler do
  begin
    // you can alternatively set the IOHandler.DefStringEncoding
    // instead of passing the encoding as a parameter...
    receivedtext := ReadString(ReadLongInt, enUTF8);
  end;
  if receivedtext <> '' then
  begin
    // ShowMessage() is not thread-safe...
    MessageBox(0, PChar(receivedtext), PChar(Application.Title), MB_OK);
  end;
end;

BTW, WriteLn()/ReadLn() do not have any length restrictions, they can handle big strings as long as there is available memory (and the text being sent does not have any line breaks in it). You are probably being confused by ReadLn() being subject to the IOHandler.MaxLineLength , which is set to 16K characters by default, but you can bypass that:

procedure TForm1.sendtext(index: integer; const txt: string);
va
  List: TList;
  AContext: TIdContext;
begin
  List := idTcpServer1.Contexts.LockList;
  try
    AContext := TIdContext(List[index]);
    // you can alternatively set the IOHandler.DefStringEncoding
    // instead of passing the encoding as a parameter...
    AContext.Connection.IOHandler.WriteLn(Trim(txt), enUTF8);
  finally
    idTcpServer1.Contexts.UnlockList;
  end;
end;

procedure TIndyClient.Execute;
var
  receivedtext: string;
begin
  // you can alternatively set the IOHandler.DefStringEncoding
  // and IOHandler.MaxLineLength instead of passing them as parameters...
  receivedtext := Form1.IdTCPClient1.IOHandler.ReadLn(LF, -1, MaxInt, enUTF8);
  if receivedtext <> '' then
  begin
    // ShowMessage() is not thread-safe...
    MessageBox(0, PChar(receivedtext), PChar(Application.Title), MB_OK);
  end;
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM