garbled byte offset when receiving data from Socket

R

Ronodev.Sen

i have a C# program that is sending data in a byte array through a
socket.

the VC++ application server receives data in teh following format....

typedef struct advice
{
header sHdr;
char Code[33];
char pn[11];
char State[4];
char szType[4];
char szTravelDate[9];
char szAmount[13];
char szMethod[7];
char CATID[16];
long lStan;
...
}

the weird part is that EVERY char array after lStan is missing 3
characters.

if i do a QUICKWATCH in VC++, i get the value of lStan as "1128415488".
converting this to a byte array , yields the bytes {0,65,66,67} - which
is the first 3 values of the field after lStan.(the field after lStan
has 'ABCDEF')

i CANT use any structures, marshalled or otherwise at the C# end ,
because my structure definitions come out of a XML Schema document.

conversion routine for the value in C#


int nData = int.Parse(strTempData);
//convert to Byte Array; this.bPvtData =
BitConverter.GetBytes(nData);


this converts 3652 into byte array = {68,14, 0 , 0}

something is evidently happening to this when it comes out of the
Socket ... either that or VC++ is not interpreting the size of the
'long' variable (which im passing as a Int32)

please help!
 
M

Mark Harris

A long is a Int64, as per documentation:
Type Range Size .NET Framework type
long –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Signed 64-bit
integer System.Int64


Hope that helps :)
 
R

Ronodev.Sen

thanks a ton Mark... but actually i did consider that fact and am using
a Int32 at C# end,

because my VC++ long (int) is a 32-bit Integer.
 
J

Jon Skeet [C# MVP]

i have a C# program that is sending data in a byte array through a
socket.

the VC++ application server receives data in teh following format....

typedef struct advice
{
header sHdr;
char Code[33];
char pn[11];
char State[4];
char szType[4];
char szTravelDate[9];
char szAmount[13];
char szMethod[7];
char CATID[16];
long lStan;
...
}

the weird part is that EVERY char array after lStan is missing 3
characters.

if i do a QUICKWATCH in VC++, i get the value of lStan as "1128415488".
converting this to a byte array , yields the bytes {0,65,66,67} - which
is the first 3 values of the field after lStan.(the field after lStan
has 'ABCDEF')

It sounds like it's CATID that's causing the problem then. How are you
transmitting that?

Jon
 
R

Ronodev.Sen

hello again Jon,

well i observed that the difference between the VC++ only
implementation and the C# - VC++ implementation is that
the padding bytes are inserted BEFORE the last 'long' value of the
structure.

is that what you mean to say ?

thanks again
 
J

Jon Skeet [C# MVP]

hello again Jon,

well i observed that the difference between the VC++ only
implementation and the C# - VC++ implementation is that
the padding bytes are inserted BEFORE the last 'long' value of the
structure.

is that what you mean to say ?

I'm not entirely sure what you mean. If you're feeding data to the
socket yourself, there shouldn't be any padding involved at the .NET
end. If the VC++ end is doing padding, that *could* be the problem.
This is one of the downsides of just reading data into unmanaged
structs - it's not terribly clear what's expected.
 
R

Ronodev.Sen

good evening Jon,

well the only reason im padding the data at the .NET end is to handle
the EXTRACTION of the data at the VC++ end.

are there any padding guidelines that you are aware of ?

i figure i'll have to check every field type and then pad the previous
fields accordingly.


thanks again
 
J

Jon Skeet [C# MVP]

good evening Jon,

well the only reason im padding the data at the .NET end is to handle
the EXTRACTION of the data at the VC++ end.

Yes - but my point is that if the VC++ end explicitly read the data a
field at a time, the data format would be a lot clearer.
are there any padding guidelines that you are aware of ?

I'm afraid not - there will be some around, I'm sure, but I don't know
them.
i figure i'll have to check every field type and then pad the previous
fields accordingly.

Yup.
 
R

Ronodev.Sen

hello again Jon,

well the VC++ code DOES read the data coming out of the socket into the
structure (from my first message).

it just doesnt read it in the properly aligned order (ie ... it reads
the long value offset by 3 bytes)

snippet --- >

// Cast to request packet
pPass = (ADVICE_STRUCT)pCliThread->pData; //the pCliThread->pData is
the data coming out of the socket at the VC++ end

now if i look at the byte arrays at the C# end ... the long value is
the SAME as the one in the VC++ array (68,14,0,0)..

its just starting from buffer position 120 instead of buffer position
123 (where its expected in the VC++ struct).

anyway, thanks a lot.. im guessing ill have to go through every
element, find its type and then pad the PREVIOUS string accordingly.
 
J

Jon Skeet [C# MVP]

well the VC++ code DOES read the data coming out of the socket into the
structure (from my first message).

Exactly - and that's the problem. Because it doesn't explicitly read it
field by field, it just reads it as one lump, the precise nature of
that lump isn't very clear.

anyway, thanks a lot.. im guessing ill have to go through every
element, find its type and then pad the PREVIOUS string accordingly.

You actually probably need to keep track of the offset, work out what
kind of alignment the "current" type uses, and pad accordingly. I
wouldn't think of it as padding the previous field though - it's
padding *between* the fields.

Jon
 
C

ConfNoob

hey Jon,

way im doing it now is ... discovering the type of each field...
checking if the sum of the bytes till now + size of current field is
divisible by 4 ... if not ... pad bytes.

if the type is System.String... im not padding it at all ...

thanks a ton for your help!
 
J

Jon Skeet [C# MVP]

ConfNoob said:
way im doing it now is ... discovering the type of each field...
checking if the sum of the bytes till now + size of current field is
divisible by 4 ... if not ... pad bytes.

if the type is System.String... im not padding it at all ...

That might do it - to be honest, I'm far from an expert (read: I know
nothing!) on alignment in unmanaged C/C++. I suspect you're best off
either looking at the documentation or asking in a C/C++ group for what
the exact rules are.
 
B

Bill Butler

Jon Skeet said:
That might do it - to be honest, I'm far from an expert (read: I know
nothing!) on alignment in unmanaged C/C++. I suspect you're best off
either looking at the documentation or asking in a C/C++ group for what
the exact rules are.

Padding out to multiples of 4 should do the trick (align binary data on a Word boundary)
However, I have never coded on a 64 bit platform, so I am not sure if double word alignment is
required for anything.

Good luck
Bill
 
C

ConfNoob

thanks Bill,

for now this will be a 32-bit platform application.

i'll let you folks know how it comes along.

thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top