Reputation: 102
I am trying to exchange data between a IdTCPServer and an IdTCPClient using a collection that I convert to a stream before I send it over the network. Unfortunately, no matter how I try, I can't seem to pass the stream between the client and the server. The code always hangs on the IdTCPClient1.IOHandler.ReadStream(myStream, -1, True) line.
The relevant portion of my code is shown below:
Client side
with ClientDataModule do
begin
try
try
intStreamSize := StrToInt(IdTCPClient1.IOHandler.ReadLn); // Read stream size
IdTCPClient1.IOHandler.ReadStream(myStream, -1, True); // Read record stream
finally
ReadCollectionFromStream(TCustomer, myStream);
end;
except
ShowMessage('Unable to read the record from stream');
end;
end;
Server side
try
try
SaveCollectionToStream(ACustomer, MStream);
finally
MStream.Seek(0, soFromBeginning);
IOHandler.WriteLn(IntToStr(MStream.Size)); // Send stream size
IOHandler.Write(MStream, 0); // Send record stream
end;
except
ShowMessage('Unable to save the record to stream');
end;
I would greatly appreciate your assistance with solving this problem.
Thanks,
JDaniel
Upvotes: 0
Views: 3951
Reputation: 597016
You are setting the AReadUntilDisconnect
parameter of ReadStream()
to True, which tells it to keep reading until the connection is closed. You need to set the parameter to False instead. You also need to pass in the stream size in the AByteCount
parameter, since you are sending the stream size separately so you have to tell ReadStream()
how much to actually read.
Try this:
Client:
with ClientDataModule do
begin
try
intStreamSize := StrToInt(IdTCPClient1.IOHandler.ReadLn);
IdTCPClient1.IOHandler.ReadStream(myStream, intStreamSize, False);
myStream.Position := 0;
ReadCollectionFromStream(TCustomer, myStream);
except
ShowMessage('Unable to read the record from stream');
end;
end;
Server:
try
SaveCollectionToStream(ACustomer, MStream);
MStream.Position := 0;
IOHandler.WriteLn(IntToStr(MStream.Size));
IOHandler.Write(MStream);
except
ShowMessage('Unable to save the record to stream');
end;
If you can change your protocol, then you can let Write()
and ReadStream()
exchange the stream size internally for you, like this:
Client:
with ClientDataModule do
begin
try
// set to True to receive a 64bit stream size
// set to False to receive a 32bit stream stream
IdTCPClient1.IOHandler.LargeStream := ...;
IdTCPClient1.IOHandler.ReadStream(myStream, -1, True);
myStream.Position := 0;
ReadCollectionFromStream(TCustomer, myStream);
except
ShowMessage('Unable to read the record from stream');
end;
end;
Server:
try
SaveCollectionToStream(ACustomer, MStream);
MStream.Position := 0;
// set to True to send a 64bit stream size
// set to False to send a 32bit stream stream
IOHandler.LargeStream := ...;
IOHandler.Write(MStream, 0, True);
except
ShowMessage('Unable to save the record to stream');
end;
Upvotes: 1