Question

I'm not sure if this is possible but here it goes. Usually I send strings like this...

Connection.IOHandler.WriteLn('alpha');
Connection.IOHandler.WriteLn('bravo');
Connection.IOHandler.WriteLn('charley');
//and so on..

But what if I want to send it in just one go, just send it all at once. Maybe I could put it on an array of strings then send the array.

someStr : array[1..3] of string = ('alpha','bravo','charley');//this could be more

...

StrListMem := TMemoryStream.Create;
try

   StrListMem.WriteBuffer(someStr[0], Length(someStr));
   StrListMem.Position:=0;

   Connection.IOHandler.Write(StrListMem, 0, True);

finally
   StrListMem.Free;
end;

I just have no idea how to this right, maybe somebody can give an example? and how the receiver(client) will read it.

EDIT:

I also having problem in how to read the stream, not sure what's wrong with this code.

Client:

msRecInfo: TMemoryStream;
  arrOf: Array of Char;

...

  msRecInfo := TMemoryStream.Create;
  try
    AContext.Connection.IOHandler.ReadStream(msRecInfo, -1, False);
    SetLength(arrOf, msRecInfo.Size div SizeOf(Char));

    msRecInfo.Position := 0;
    msRecInfo.ReadBuffer(arrOf[0], Length(arrOf) * SizeOf(Char));

  finally
    MessageBox(0,pChar(arrOf[0]),0,0);//memo1.Lines.Add(arrOf[0]);
    msRecInfo.Free;
  end;
Was it helpful?

Solution

You can write the whole array to stream in one swoop. You actually already wrote close to a correct code

StrListMem := TMemoryStream.Create;
try
   for I := 0 to Length(someStr) - 1 do
   begin
     StrListMem.WriteBuffer(someStr[I][1], Length(someStr[I]) * SizeOf(Char));
     StrListMem.WriteBuffer(sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
   end;

   StrListMem.Position:=0;    
   Connection.IOHandler.Write(StrListMem, 0, True);    
finally
   StrListMem.Free;
end;

Alternatively if you want to only work with data and abstract the transport layer away (read, easier coding) you can check out my IMC. It abstracts some things for you making it easier.

EDIT:

I added the newline character after each string as it seems to be consistent with original OP code. I don't have Delphi at hand so do not blindly copy the code please.

EDIT:

After reading the question again I realized that his goal is only to send it in one go and it is not mandatory to use a string array. So there is a better way to do it.

StrListMem := TStringList.Create;
try
  StrListMem.Add('alpha');
  StrListMem.Add('bravo');
  StrListMem.Add('charley');
  Connection.IOHandler.WriteBufferOpen;
  try
    Connection.IOHandler.Write(StrListMem);    
  finally
    Connection.IOHandler.WriteBufferClose;
  end;
finally
  StrListMem.Free;
end;

To read it

StrListMem := TStringList.Create;
try
  IdTCPClient1.IOHandler.ReadStrings(StrListMem);
finally
  StrListMem.Free;
end;

Easier and cleaner :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top