Sie sind auf Seite 1von 2

ou are making a classic newbie mistake - you are expecting the default behaviors of the

TIdIOHandler.Write(TStream) and TIdIOHandler.ReadStream() methods to match each


other, but they actually do not.

The default parameter values of TIdIOHandler.ReadStream() tell it to expect an Integer or


Int64 (depending on the value of the TIdIOHandler.LargeStream property) to preceed the
stream data to specify the length of the data.

However, the default parameter values of TIdIOHandler.Write(TStream) do not tell it to


send any such Integer/Int64 value. Thus, your use of TIdIOHandler.ReadStream() reads
the first few bytes of the record and interprets them as an Integer/Int64 (which is
926036233 given the string value you are sending), and then waits for that many bytes to
arrive, which never will so TIdIOHandler.ReadStream() does not exit (unless you set the
TIdIOHandler.ReadTimeout property to a non-infinite value).

There are also some other minor bugs/typos in your code that uses the TMemoryStream
objects outside of Indy.

Try this instead:

procedure Tform1.ButtonSendClick(Sender: TObject);


var
MIRec: Tmyrecord;
msRecInfo: TMemoryStream;
begin
MIRec.IPStr := '172.0.0.1';
msRecInfo := TMemoryStream.Create;
try
msRecInfo.Write(MIRec, SizeOf(MIRec));

// writes the stream size then writes the stream data


Client.IOHandler.Write(msRecInfo, 0, True);
finally
msRecInfo.Free;
end;
end;

procedure TServerFrmMain.ServerExecute(AContext: TIdContext);


var
MIRec: Tmyrecord;
msRecInfo: TMemoryStream;
begin
msRecInfo := TMemoryStream.Create;
try
// reads the stream size then reads the stream data
AContext.Connection.IOHandler.ReadStream(msRecInfo, -1, False);

msRecInfo.Position := 0;
msRecInfo.Read(MIRec, SizeOf(MIRec));
...
finally
msRecInfo.Free;
end;
end;

Or this:
procedure Tform1.ButtonSendClick(Sender: TObject);
var
MIRec: Tmyrecord;
msRecInfo: TMemoryStream;
begin
MIRec.IPStr := '172.0.0.1';
msRecInfo := TMemoryStream.Create;
try
msRecInfo.Write(MIRec, SizeOf(MIRec));

// does not write the stream size, just the stream data
Client.IOHandler.Write(msRecInfo, 0, False);
finally
msRecInfo.Free;
end;
end;

procedure TServerFrmMain.ServerExecute(AContext: TIdContext);


var
MIRec: Tmyrecord;
msRecInfo: TMemoryStream;
begin
msRecInfo := TMemoryStream.Create;
try
// does not read the stream size, just the stream data
AContext.Connection.IOHandler.ReadStream(msRecInfo, SizeOf(MIRec),
False);

msRecInfo.Position := 0;
msRecInfo.Read(MIRec, SizeOf(MIRec));
...
finally
msRecInfo.Free;
end;
end;

Alternatively, you can send the record using TIdBytes instead of TStream:

procedure Tform1.ButtonSendClick(Sender: TObject);


var
MIRec: Tmyrecord;
Buffer: TIdBytes;
begin
MIRec.IPStr := '172.0.0.1';
Buffer := RawToBytes(MIRec, SizeOf(MIRec));
Client.IOHandler.Write(Buffer);
end;

procedure TServerFrmMain.ServerExecute(AContext: TIdContext);


var
MIRec: Tmyrecord;
Buffer: TIdBytes;
begin
AContext.Connection.IOHandler.ReadBytes(Buffer, SizeOf(MIRec));
BytesToRaw(Buffer, MIRec, SizeOf(MIRec));
...
end;

Das könnte Ihnen auch gefallen