🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
4 messages
4 total messages Started by Marijan Sever Sun, 06 Jan 2008 11:47
How to transport 0x00 through TIdBytes
#521
Author: Marijan Sever
Date: Sun, 06 Jan 2008 11:47
39 lines
2226 bytes
Would you be so kind and help?

I have been using UDP communication for a while (BC++ 6.0). While 
transfering the projects from BDS2006 C++ to CodeGear 2007 C++,  I have some 
problems with sending 0x00 byte.
Indy 9 (BDS2006) uses char[] for transport buffer, Indy 10 uses TIdBytes for 
transport buffer (as far as I know).
I can not use TIdBytes for transport 0x00.
We are using TIdUDPServer and TIdUDPClient components for industrial 
automation communication, where 0x00 is valid data.
The sample code is below (tried to use other ways to fill TIdBytes, but 
allways with same result).

//-------------------------------------------------------------------------
 TIdBytes cbuf;
 char c[8];

 c[0]=0x01;
 c[1]=0x00;
 c[2]='a';
 c[3]='b';
 c[4]=0x00;
 c[5]='c';
 c[6]='d';

 cbuf.Length=8;
 RawToBytesF(cbuf,c,8);

UdpServ->SendBuffer(shost,iport,cbuf);

//-------------------------------------------------------------------------
//Getting as follows; cbuf[0]=0x01,cbuf[1]=0x00 - and nothing further

It seems that TIdBytes uses 0x00 as null termination for string. Am I doing 
something wrong or this kind is a feature of Indy 10 (or bug) ?

Appreciate any suggestion..

Best regards, Marijan
Re: How to transport 0x00 through TIdBytes
#524
Author: Remy Lebeau (TeamB)
Date: Mon, 07 Jan 2008 17:40
55 lines
2775 bytes
"Marijan Sever" <marijan.sever@codel.hr> wrote in message 
news:4780bfd0@newsgroups.borland.com...

> I have some problems with sending 0x00 byte.

Then you are not sending the bytes correctly, because Indy does not treat 
0x00 any differently than other bytes.

> Indy 9 (BDS2006) uses char[] for transport buffer

No, it used void* instead, which meant you could pass in just about anything 
you wanted.

> Indy 10 uses TIdBytes for transport buffer (as far as I know).

There are several different ways to send buffers in Indy 10.  TIdBytes is 
just one of them.

> I can not use TIdBytes for transport 0x00.

0x00 works fine with TIdBytes.

> TIdBytes cbuf;
> char c[8];

You don't need a separate char[].  You can fill the TIdBytes directly, ie:

    TIdBytes cbuf;
    cbuf.Length = 8;
    cbuf[0] = 0x01;
    cbuf[1] = 0x00;
    cbuf[2] = 'a';
    cbuf[3] = 'b';
    cbuf[4] = 0x00;
    cbuf[5] = 'c';
    cbuf[6] = 'd';
    cbuf[7] = ?; // what are you putting here???  You allocate 8 slots but 
only fill in 7 of them

> //Getting as follows

Getting where?  Were are you looking at the data from?  The receiver end? 
If you are sending 8 bytes but only receiving 2 bytes, then that is all you 
are receiving.  What do you have set for the TIdUDPServer.BufferSize 
property?  What does your OnUDPRead event handler look like?  Have you tried 
using a packet sniffer to verify all of the bytes are arriving on the 
receiver's network adpater to begin with?

> It seems that TIdBytes uses 0x00 as null termination for string.

No, it does not.  The full Length of the buffer is always used.


Gambit 
Re: How to transport 0x00 through TIdBytes
#543
Author: Marijan Sever
Date: Sun, 13 Jan 2008 09:05
123 lines
4305 bytes
Remy, than you very much on your support.

> Then you are not sending the bytes correctly, because Indy does not treat
> 0x00 any differently than other bytes.

Possible, this is the reason that I asking for help.

>No, it used void* instead, which meant you could pass in just about
>anything
> you wanted.

OK, void and I used to send char array.

> > Indy 10 uses TIdBytes for transport buffer (as far as I know).
> There are several different ways to send buffers in Indy 10.  TIdBytes is
> just one of them.

UPS...? What are the other ways? I checked TIdUDPServer Indy10 help and 
found
as follows(TIdUDPBase):

//----------------------------1
procedure Send(
    AHost: string,
    const APort: Integer,
    const AData: string
);
//----------------------------2
procedure SendBuffer(
    AHost: string,
    const APort: Integer,
    const ABuffer: TIdBytes
); virtual; overload;
//----------------------------3
procedure SendBuffer(
    AHost: string,
    const APort: Integer,
    const AIPVersion: TIdIPVersion,
    const ABuffer: TIdBytes
); virtual; overload;
//----------------------------
Allmost similar is in TidSocketHandle...
Would you be so kind and specify what are other options.

> > TIdBytes cbuf;
> > char c[8];
> You don't need a separate char[].  You can fill the TIdBytes directly, ie:

Yes, I use this way, but in the sample seemed convenient to use char because
of  clearity

>     TIdBytes cbuf;
>     cbuf.Length = 8;
>     cbuf[0] = 0x01;
>     cbuf[1] = 0x00;
>     cbuf[2] = 'a';
>     cbuf[3] = 'b';
>     cbuf[4] = 0x00;
>     cbuf[5] = 'c';
>     cbuf[6] = 'd';
>     cbuf[7] = ?; // what are you putting here???  You allocate 8 slots but
> only fill in 7 of them

cbuf[7] - sorry forgot in my sample.It can be 'e'.

>  Getting where?  Were are you looking at the data from?

I have already try exactly as in your sample and in the debugger mode in the 
Local
variable window I have as follows:

      cbuf
      |-----Data
            |------[0]-------'\x01'1(0x01)
            |------[1]-------'\x00'0(0x00)

...and nothing else. Have you tried this and get other results?

>  The receiver end?

The same as in Local variable window


> If you are sending 8 bytes but only receiving 2 bytes, then that is all
> you
> are receiving.  What do you have set for the TIdUDPServer.BufferSize
> property?

Default, 8192 bytes

>  What does your OnUDPRead event handler look like?

//----------------------------------------------------
void __fastcall UDPClientTh::Execute()
{
try
{
    pUDPSock->ClSock->ReceiveBuffer(RxBuf,500);
    Synchronize(&ProcessMsg);
}
catch (Exception &E)
{
   //Do something...
}
}
//----------------------------------------------------

//UDDPSock is main UDP thread
//ClSock is TIdUDPClient
//UDPClientTh is receiving thread
//RxBuf is TIdBytes, initialized as follows: RxBuf.Length=8192;

> Have you tried
> using a packet sniffer to verify all of the bytes are arriving on the
> receiver's network adpater to begin with?

Yes, Ethereal... Same.

> > It seems that TIdBytes uses 0x00 as null termination for string.
>
> No, it does not.  The full Length of the buffer is always used.

Hm, I believe you, but can not achieve this till now.
Re: How to transport 0x00 through TIdBytes
#545
Author: Remy Lebeau (TeamB)
Date: Mon, 14 Jan 2008 17:36
54 lines
2834 bytes
"Marijan Sever" <marijan.sever@codel.hr> wrote in message 
news:4789d472@newsgroups.borland.com...

> UPS...? What are the other ways?

Sorry, I forgot that UDP does not have as many options as TCP.  In TCP, you 
could use a TStream, TIdBytes, or String.  In UDP, you don't have the 
TStream option.

> I have already try exactly as in your sample and in the debugger
> mode in the Local variable window I have as follows:
>
>      cbuf
>      |-----Data
>            |------[0]-------'\x01'1(0x01)
>            |------[1]-------'\x00'0(0x00)
>
> ...and nothing else. Have you tried this and get other results?

Did you try expanding the range of the Inspector to 8 slots?  You know the 
TIdBytes is allocated to 8 bytes long, but only 2 bytes are being displayed. 
That should tell you that it is the Inspector, not the code, that is 
stopping on a 0x00 byte.

>    pUDPSock->ClSock->ReceiveBuffer(RxBuf,500);

What are you setting the Length of RxBuf to beforehand.  You have to set it 
before calling ReceiveBuffer() so it knows the maximum numbe of bytes to 
read.  What value is ReceiveBuffer() returning?  That is the number of bytes 
that are actually read into the TIdBytes.  You should be resizing the 
TIdBytes to the desired Length every time beforehand, and then resizing it 
to whatever ReceiveBuffer() returns.  ReceiveBuffer() will not size the 
TIdBytes for you.  For example:

    try
    {
        RxBuf.Length = 8192;
        RxBuf.Length = pUDPSock->ClSock->ReceiveBuffer(RxBuf, 500);
        //...
    }
    catch(...)
    {
        //...
    }

> catch (Exception &E)

Always catch exceptions by 'const' reference instead:

    catch (const Exception &E)


Gambit 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads