🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
10 messages
10 total messages Started by Stefano Bonifazi Tue, 15 May 2007 18:10
Serializing struct for TCP sending
#1113
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 18:10
37 lines
2157 bytes
Hi all!:)
  In short I would like to send whole structure instances by using 
TCP-IP.. for example through Indy TCPClient.
The first and secure way is to serialize the members of a structure in a 
buffer and then send them with

procedure WriteBuffer(const ABuffer; AByteCount: Longint; const 
AWriteNow: boolean);

Anyway for simple structures for example:

struct
{
  char name[255];
  int intnum;
  float fnum;
} my_struct;

it seems to work even something like that:

WriteBuffer (&myStruct,sizeof(my_struct));

that means that in memory they are simply placed one right the other.. 
so on the other side I can receive the buffer by knowing that structure 
size, and cast the buffer to that struct pointer!

My question is: does that work always on every compiler? May the 
procedure of sending that buffer to a program, running on a different 
OS, produce a different object on destination even by using the same 
struct type on the second program?

  Maybe my problem is silly,and the answer obvious, but I am not sure of 
what a compiler does exactly allocating data when I create structures or 
classes, and what happen to data when sent by Indy or TCP-IP.

Thank U very much in advance,
Stefano B.
Re: Serializing struct for TCP sending
#1114
Author: Bob Gonder
Date: Tue, 15 May 2007 19:00
42 lines
2485 bytes
Stefano Bonifazi wrote:

>My question is: does that work always on every compiler?

Yes, but the results may not be what you want them to be.

> May the 
>procedure of sending that buffer to a program, running on a different 
>OS, produce a different object on destination even by using the same 
>struct type on the second program?

Yes.
See Endian issues.
See also alignment issues.

>  Maybe my problem is silly,and the answer obvious, but I am not sure of 
>what a compiler does exactly allocating data when I create structures 

Depends on the alignment setting.
The default is probably for your char name[255] to be 256 bytes of
storage
Most compilers align the internal items for fast processor access.
So, a compiler for 8086 might default to byte-alignment while one for
pentium would be 4 byte align, and perhaps one for mainframe would be
64 or even 128 bit aligned.
This alignment is overridable by the programmer.

> and what happen to data when sent by Indy or TCP-IP.

It is sent as-is.

Bottom line:
If you are sending exclusively to your own apps, you can do whatever
you want (send raw structures).
If you are sending to someone else's app, or your app that someone
compiles for their harware, you might be better off converting
integers and such into network-endian format and transmit the
individual pieces.


You might Google this group for endian
http://tinyurl.com/28s62e
Re: Serializing struct for TCP sending
#1116
Author: Remy Lebeau (TeamB)
Date: Tue, 15 May 2007 19:02
13 lines
1443 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message
news:hevj4394fkkbve5uiuicaf1614234a44j3@4ax.com...

> If you are sending to someone else's app, or your app that
> someone compiles for their harware, you might be better off
> converting integers and such into network-endian format

You should also use 1-byte alignment for your structures so that there
is no unnecessary padding added by the compiler.


Gambit
Re: Serializing struct for TCP sending
#1117
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 19:54
17 lines
1596 bytes
Hi thank U very much to both!



>> If you are sending to someone else's app, or your app that
>> someone compiles for their harware, you might be better off
>> converting integers and such into network-endian format

sorry how? I always used Indy SendBuffer and on the other side even from 
Linux they receive fine!
> 
> You should also use 1-byte alignment for your structures so that there
> is no unnecessary padding added by the compiler.

U mean in "advanced compiler" options, "data alignment" right?

Thank U again!
Re: Serializing struct for TCP sending
#1118
Author: Remy Lebeau (TeamB)
Date: Tue, 15 May 2007 20:33
60 lines
2873 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:464a101b@newsgroups.borland.com...

> I always used Indy SendBuffer and on the other side even
> from Linux they receive fine!

Windows and Linux run on the same hardware architecture, so the endian
is the same.  But if you were to exchange data with to a Mac or other
non-PC machine, the endian would likely not match.  Read/WriteBuffer()
do not perform any endian conversions at all.
Read/WriteInteger/Cardinal/SmallInt(), on the other hand, do perform
conversions from/to network byte ordering by default.  All systems
understand network byte ordering, and the socket API provides
functions (which Indy wraps internally) to convert numbers between
network byte ordering (which is universal across networks) and host
byte ordering (which is specific to the machine being run on).  So,
what you could do is send the individual members of your struct
separately, ie:

    my_struct s;

    TCPClient->WriteBuffer(s.name, 255);
    TCPClient->WriteInteger(s.intnum);
    // and so on...

    TCPClient->ReadBuffer(s.name, 255);
    s.intnum = TCPClient->ReadInteger();
    // and so on...

Also, you might want to stay away from floating point numbers, if you
can.  The byte size and binary representation may work differently on
different hardware architectures as well, regardless of the endian
used.

> U mean in "advanced compiler" options, "data alignment" right?

No.  That is a global setting that effects the entire application as a
whole.  That would be very dangerous and error-prone.  What you should
do instead is wrap your individual structs with #pragma pack
statements instead, ie:

    #pragma pack(push, 1)
    struct my_struct
    {
        //...
    };
    #pragma pack(pop)

Or:

    #include <pshpack1.h>
    struct my_struct
    {
        //...
    };
    #include <poppack.h>


Gambit
Re: Serializing struct for TCP sending
#1119
Author: Bob Gonder
Date: Tue, 15 May 2007 20:42
7 lines
1183 bytes
Stefano Bonifazi wrote:

>>> converting integers and such into network-endian format
>
>sorry how? 

See the link in my first message
Re: Serializing struct for TCP sending
#1120
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 21:02
62 lines
2629 bytes
Hi Thank U very much!

Remy Lebeau (TeamB) ha scritto:
>     my_struct s;
> 
>     TCPClient->WriteBuffer(s.name, 255);
>     TCPClient->WriteInteger(s.intnum);
>     // and so on...
> 

what I exactly did always :)

>     TCPClient->ReadBuffer(s.name, 255);
>     s.intnum = TCPClient->ReadInteger();
>     // and so on...

Wish they used Indy on Linux..they uses simple Liux socket API.. hope 
they perform conversion from Network endian to Host machine endian as 
well as!!

> 
> Also, you might want to stay away from floating point numbers, if you
> can.  The byte size and binary representation may work differently on
> different hardware architectures as well, regardless of the endian
> used.

Engineering numbers are very seldom integers! .. So what to do?

> 
>> U mean in "advanced compiler" options, "data alignment" right?
> 
> No.  That is a global setting that effects the entire application as a
> whole.  That would be very dangerous and error-prone.  

Oh really?? I wonder why they put the option if that is dangerous!
Thank U!!

What you should
> do instead is wrap your individual structs with #pragma pack
> statements instead, ie:
> 
>     #pragma pack(push, 1)
>     struct my_struct
>     {
>         //...
>     };
>     #pragma pack(pop)
> 
> Or:
> 
>     #include <pshpack1.h>
>     struct my_struct
>     {
>         //...
>     };
>     #include <poppack.h>

Thank U.. never heard about those before!


My best regards!
Stefano B.
Re: Serializing struct for TCP sending
#1121
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 21:03
9 lines
1234 bytes

Bob Gonder wrote:
> See the link in my first message
> 
> 
> 

Thank U again!
Re: Serializing struct for TCP sending
#1122
Author: Remy Lebeau (TeamB)
Date: Tue, 15 May 2007 23:02
16 lines
1550 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:464a200d@newsgroups.borland.com...

> Wish they used Indy on Linux..they uses simple Liux socket API..

Indy works on Linux, and is built on top of the same API.

> hope they perform conversion from Network endian to Host
> machine endian as well as!!

Everybody does.  It is the only way to ensure proper data integrity
over a network across different platforms.


Gambit
Re: Serializing struct for TCP sending
#1123
Author: Stefano Bonifazi
Date: Wed, 16 May 2007 11:26
30 lines
2101 bytes
Hi Mr. Lebeau! Thank U for Ur answer!


>> Wish they used Indy on Linux..they uses simple Liux socket API..
> 
> Indy works on Linux, and is built on top of the same API.

Sure, sorry my english:( I meant I wished they(the programmers on Linux 
   I am working with) would use Indy, but they don't, even though after 
my recommendation! :(

> 
>> hope they perform conversion from Network endian to Host
>> machine endian as well as!!
> 
> Everybody does.  It is the only way to ensure proper data integrity
> over a network across different platforms.

I c.. that's why that works even though I never did anything special to 
take care of it before :)



Please have U suggestiond about sending floating point numbers? I can't 
do without! Should I convert them to string representation and send the 
strings instead to be sure nothing odd happens?

Thank U again!

Stefano B.
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