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
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 18:10
Date: Tue, 15 May 2007 18:10
37 lines
2157 bytes
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
Author: Bob Gonder
Date: Tue, 15 May 2007 19:00
Date: Tue, 15 May 2007 19:00
42 lines
2485 bytes
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
Author: Remy Lebeau (TeamB)
Date: Tue, 15 May 2007 19:02
Date: Tue, 15 May 2007 19:02
13 lines
1443 bytes
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
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 19:54
Date: Tue, 15 May 2007 19:54
17 lines
1596 bytes
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
Author: Remy Lebeau (TeamB)
Date: Tue, 15 May 2007 20:33
Date: Tue, 15 May 2007 20:33
60 lines
2873 bytes
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
Author: Bob Gonder
Date: Tue, 15 May 2007 20:42
Date: Tue, 15 May 2007 20:42
7 lines
1183 bytes
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
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 21:02
Date: Tue, 15 May 2007 21:02
62 lines
2629 bytes
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
Author: Stefano Bonifazi
Date: Tue, 15 May 2007 21:03
Date: Tue, 15 May 2007 21:03
9 lines
1234 bytes
1234 bytes
Bob Gonder wrote: > See the link in my first message > > > Thank U again!
Re: Serializing struct for TCP sending
Author: Remy Lebeau (TeamB)
Date: Tue, 15 May 2007 23:02
Date: Tue, 15 May 2007 23:02
16 lines
1550 bytes
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
Author: Stefano Bonifazi
Date: Wed, 16 May 2007 11:26
Date: Wed, 16 May 2007 11:26
30 lines
2101 bytes
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