 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kiwi Guest
|
Posted: Mon Aug 14, 2006 7:58 am Post subject: Problem reading data from TidIOHandler |
|
|
I have the following code
var
Buf: TidBytes;
fMem: TMemoryStream;
begin
fMem:= TMemoryStream.Create;
try
IOHandler.ReadBytes(Buf, 1, False);
Size:= Buf[0];
IOHandler.ReadBytes(Buf, Size, False);
fMem.Clear;
BytesToRaw(Buf, fMem, Size);
fMem.Seek(0,soFromBeginning); <==== I get a EAccessViolation.
finally
fMem.Free;
end;
end;
I seem to always end up with problems using streams - so sorry if this is a
stupid question but it has me really stumped.
Thanks in advance |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Mon Aug 14, 2006 10:44 pm Post subject: Re: Problem reading data from TidIOHandler |
|
|
"Kiwi" <glen (AT) custommadesoftware (DOT) co.nz> wrote in message
news:44dfe6d2 (AT) newsgroups (DOT) borland.com...
| Quote: | IOHandler.ReadBytes(Buf, 1, False);
|
Use ReadByte() instead:
Size := IOHandler.ReadByte;
| Quote: | IOHandler.ReadBytes(Buf, Size, False);
|
Use ReadStream() instead:
fMem.Clear;
IOHandler.ReadStream(fMem, Size, False);
| Quote: | BytesToRaw(Buf, fMem, Size);
fMem.Seek(0,soFromBeginning); <==== I get a EAccessViolation.
|
You are trying to write your data to the memory address where the stream
object itself resides, not to the memory address where the stream stores its
data buffer. You are not writing the data into the stream at all. To do
that, you would have to set the stream's Size property (to preallocate the
buffer to the proper size), and then write the data into the stream's Memory
property, ie:
fMem.Size := Size;
BytesToRaw(Buf, fMem.Memory, Size);
| Quote: | I seem to always end up with problems using streams
|
You aren't using them properly.
Gambit |
|
| Back to top |
|
 |
Paul Nicholls Guest
|
Posted: Tue Aug 15, 2006 8:11 am Post subject: Re: Problem reading data from TidIOHandler |
|
|
"Kiwi" <glen (AT) custommadesoftware (DOT) co.nz> wrote in message
news:44e14282 (AT) newsgroups (DOT) borland.com...
| Quote: | I am still having problems handling the data from the IOHandler
This is the code on the Client Side. The first 4 bytes that are recieved
indicate the length of the stream.
Here is the Server side code which seems to be working fine
fMem.Position:= 0;
Buf:= RawToBytes(fMem, fMem.Size);
I:= Length(Buf); // = 73050
SetLength(Buf, Length(Buf) +4);
Move(Buf[0], Buf[4], Length(Buf));
Move(I, Buf[0], 4); //90, 29, 1, 0
AContext.Connection.IOHandler.Write(Buf);
Here is the Client side:
fMem:= TMemoryStream.Create;
try
SetLength(Buf, 0);
IOHandler.ReadBytes(Buf, 4, False);
Move(Buf[0], Size, 4);
if Size > 0 then
IOHandler.ReadBytes(Buf, Size, False);
fMem.Clear;
BytesToRaw(Buf, fMem, Size);
fMem.Position:= 0; <=====Failing here with an access violation
fMem.Read(cmd, 4);
finally
fMem.Destroy;
end;
|
I believe you are still trying to overwrite the fMem object with the Buf
data, corrupting your fMem stream.
This is why you get the AV at that line as the previous line you are
screwing up the fMem object.
cheers,
Paul. |
|
| Back to top |
|
 |
Kiwi Guest
|
Posted: Tue Aug 15, 2006 8:11 am Post subject: Re: Problem reading data from TidIOHandler |
|
|
I am still having problems handling the data from the IOHandler
This is the code on the Client Side. The first 4 bytes that are recieved
indicate the length of the stream.
Here is the Server side code which seems to be working fine
fMem.Position:= 0;
Buf:= RawToBytes(fMem, fMem.Size);
I:= Length(Buf); // = 73050
SetLength(Buf, Length(Buf) +4);
Move(Buf[0], Buf[4], Length(Buf));
Move(I, Buf[0], 4); //90, 29, 1, 0
AContext.Connection.IOHandler.Write(Buf);
Here is the Client side:
fMem:= TMemoryStream.Create;
try
SetLength(Buf, 0);
IOHandler.ReadBytes(Buf, 4, False);
Move(Buf[0], Size, 4);
if Size > 0 then
IOHandler.ReadBytes(Buf, Size, False);
fMem.Clear;
BytesToRaw(Buf, fMem, Size);
fMem.Position:= 0; <=====Failing here with an access violation
fMem.Read(cmd, 4);
finally
fMem.Destroy;
end;
"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote in message
news:44e0b6d3$1 (AT) newsgroups (DOT) borland.com...
| Quote: |
"Kiwi" <glen (AT) custommadesoftware (DOT) co.nz> wrote in message
news:44dfe6d2 (AT) newsgroups (DOT) borland.com...
IOHandler.ReadBytes(Buf, 1, False);
Use ReadByte() instead:
Size := IOHandler.ReadByte;
IOHandler.ReadBytes(Buf, Size, False);
Use ReadStream() instead:
fMem.Clear;
IOHandler.ReadStream(fMem, Size, False);
BytesToRaw(Buf, fMem, Size);
fMem.Seek(0,soFromBeginning); <==== I get a EAccessViolation.
You are trying to write your data to the memory address where the stream
object itself resides, not to the memory address where the stream stores
its
data buffer. You are not writing the data into the stream at all. To do
that, you would have to set the stream's Size property (to preallocate the
buffer to the proper size), and then write the data into the stream's
Memory
property, ie:
fMem.Size := Size;
BytesToRaw(Buf, fMem.Memory, Size);
I seem to always end up with problems using streams
You aren't using them properly.
Gambit
|
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Wed Aug 16, 2006 1:16 am Post subject: Re: Problem reading data from TidIOHandler |
|
|
"Kiwi" <glen (AT) custommadesoftware (DOT) co.nz> wrote in message
news:44e14282 (AT) newsgroups (DOT) borland.com...
| Quote: | I am still having problems handling the data from the IOHandler
|
That is because you are still not handling it correctly.
| Quote: | Here is the Server side code which seems to be working fine
|
Wrong. It is not working correctly, because of the following ...
| Quote: | Buf:= RawToBytes(fMem, fMem.Size);
|
That line is wrong. As I explained to you earlier, in order to access the
TMemoryStream's content, you must use its Memory property, ie:
Buf := RawToBytes(fMem.Memory, fMem.Size);
You are not doing that, so you are trying to convert the raw data that is
located at the memory address where the TMemoryStream object itself is
stored, not where its data buffer is stored. The two are NOT at the same
memory address!
| Quote: | Move(Buf[0], Buf[4], Length(Buf));
|
That is also wrong. You are writing data past the end of the buffer, so you
are going to corrupt the surrounding memory, if not cause an AV instead.
Since you are using the new length instead of the original length, you need
to subtract 4 when copying the bytes:
Move(Buf[0], Buf[4], Length(Buf)-4);
| Quote: | BytesToRaw(Buf, fMem, Size);
fMem.Position:= 0; <=====Failing here with an access violation
|
That is because you are still overwriting the value stored in the
TMemoryStream pointer incorrectly, as I explained to you earlier. You MUST
set the TMemoryStream's Size property and then copy the bytes into the
TMemoryStream's Memory property instead, ie:
fMem.Size := Size;
BytesToRaw(Buf, fMem.Memory, Size);
With that said, you shouldn't be trying to stuff the TIdBytes length into
the TIdBytes itself to begin with. Use the Write(Integer) and ReadInteger()
methods instead, ie:
--- server ---
Buf := RawToBytes(fMem.Memory, fMem.Size);
AContent.Connection.IOHandler.Write(Integer(Length(Buf)));
AContext.Connection.IOHandler.Write(Buf);
--- client ---
fMem := TMemoryStream.Create;
try
SetLength(Buf, 0);
Size := IOHandler.ReadInteger;
if Size > 0 then IOHandler.ReadBytes(Buf, Size, False);
fMem.Size := Size;
BytesToRaw(Buf, fMem.Memory, Size);
fMem.Position := 0;
fMem.Read(cmd, 4);
finally
fMem.Free;
end;
Alternatively:
--- server ---
fMem.Position := 0;
ReadTIdBytesFromStream(fMem, Buf, fMem.Size);
AContent.Connection.IOHandler.Write(Integer(Length(Buf)));
AContext.Connection.IOHandler.Write(Buf);
--- client ---
fMem := TMemoryStream.Create;
try
SetLength(Buf, 0);
Size := IOHandler.ReadInteger;
if Size > 0 then IOHandler.ReadBytes(Buf, Size, False);
WriteTIdBytesToStream(fMem, Buf, Size);
fMem.Position := 0;
fMem.Read(cmd, 4);
finally
fMem.Free;
end;
Even better, as I suggested to you earlier, you should get rid of the
TIdBytes altogether and read/write the streams directly. Write(Stream) and
ReadStream() even handle the 4-byte length for you automatically.
--- server ---
AContext.Connection.IOHandler.Write(fMem, 0, True);
--- client ---
fMem := TMemoryStream.Create;
try
IOHandler.ReadStream(fMem, -1, False);
fMem.Position := 0;
fMem.Read(cmd, 4);
finally
fMem.Free;
end;
Gambit |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|