How to copy a integer length in a array.

M

Martin Greul

Hello together,

I want to copy a integer length in a array.
How can I do that?

I have a solution with unsafe.
http://www1.minpic.de/bild_anzeigen.php?id=79735&key=36633275&ende
But I think is the wrong way.

Maybe somebody can help me.

Thanks.


Greetng Martin
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

unsafe void SendTelegram(string telegramm)
//void SendTelegram(string telegramm)
{
BinaryWriter writer = new BinaryWriter(_stream);
byte[] data = TextEncoding.GetBytes(telegramm);

int lengthInNetworkOrder =
IPAddress.NetworkToHostOrder(data.Length + 4);


int nLength = data.Length;
// ** Specification --> header (4 Byte)
Byte[] bytesSent = new Byte[nLength + 4];
fixed (byte* p = &bytesSent[0])
{
int* pi = (int*)p;
*pi = System.Net.IPAddress.NetworkToHostOrder(nLength + 4);
}
System.Array.Copy(data, 0, bytesSent, 4, nLength);
// writer.Write(lengthInNetworkOrder);
writer.Write(bytesSent);
}
 
A

Arne Vajhøj

Martin said:
I want to copy a integer length in a array.
How can I do that?
BinaryWriter writer = new BinaryWriter(_stream);
byte[] data = TextEncoding.GetBytes(telegramm);

int lengthInNetworkOrder =
IPAddress.NetworkToHostOrder(data.Length + 4);

int nLength = data.Length;
// ** Specification --> header (4 Byte)
Byte[] bytesSent = new Byte[nLength + 4];
fixed (byte* p = &bytesSent[0])
{
int* pi = (int*)p;
*pi = System.Net.IPAddress.NetworkToHostOrder(nLength + 4);
}
System.Array.Copy(data, 0, bytesSent, 4, nLength);
// writer.Write(lengthInNetworkOrder);
writer.Write(bytesSent);
}

My suggestion:
BitConverter class

Arne
 
M

Martin Greul

Hello Arne,
I want to copy a integer length in a array.
How can I do that?
BinaryWriter writer = new BinaryWriter(_stream);
byte[] data = TextEncoding.GetBytes(telegramm);

int lengthInNetworkOrder =
IPAddress.NetworkToHostOrder(data.Length + 4);

int nLength = data.Length;
// ** Specification --> header (4 Byte)
Byte[] bytesSent = new Byte[nLength + 4];
fixed (byte* p = &bytesSent[0])
{
int* pi = (int*)p;
*pi = System.Net.IPAddress.NetworkToHostOrder(nLength + 4);
}
System.Array.Copy(data, 0, bytesSent, 4, nLength);
// writer.Write(lengthInNetworkOrder);
writer.Write(bytesSent);
}

My suggestion:
BitConverter class
ok, can you make an example for me? Thanks

Greeting Martin
 
A

Arne Vajhøj

Martin said:
Hello Arne,
I want to copy a integer length in a array.
How can I do that?
BinaryWriter writer = new BinaryWriter(_stream);
byte[] data = TextEncoding.GetBytes(telegramm);

int lengthInNetworkOrder =
IPAddress.NetworkToHostOrder(data.Length + 4);

int nLength = data.Length;
// ** Specification --> header (4 Byte)
Byte[] bytesSent = new Byte[nLength + 4];
fixed (byte* p = &bytesSent[0])
{
int* pi = (int*)p;
*pi = System.Net.IPAddress.NetworkToHostOrder(nLength + 4);
}
System.Array.Copy(data, 0, bytesSent, 4, nLength);
// writer.Write(lengthInNetworkOrder);
writer.Write(bytesSent);
}

My suggestion:
BitConverter class
ok, can you make an example for me? Thanks

I would assume that the docs contains an example.

But it is very simple:

byte[] fourbytes = BitConverter.GetBytes(someintvalue);

Arne
 
P

Peter Duniho

Hello together,

I want to copy a integer length in a array.
How can I do that?

I have a solution with unsafe.
http://www1.minpic.de/bild_anzeigen.php?id=79735&key=36633275&ende
But I think is the wrong way.

Maybe somebody can help me.

Sure. Just use the line you commented out instead of all that unsafe
code. Of course, the second call to "writer.Write()" should use "data" as
the argument instead of "bytesSent" (you don't even need "bytesSent").

I will also point out that for writing, you really probably want
IPAddress.HostToNetworkOrder(). After all, you're starting with an int in
"host" order (i.e. stored locally) and sending over the network and so
want it there in "network" order. This hasn't have an effect on actual
outcome; .NET is always little-endian, and network order is always
big-endian, so the bytes get reversed regardless. But the code would be
more maintainable if you used the correct method, to make it clear which
direction the data's going.

Pete
 
M

Martin Greul

Hello Pete,
Sure. Just use the line you commented out instead of all that unsafe
code. Of course, the second call to "writer.Write()" should use "data"
as the argument instead of "bytesSent" (you don't even need "bytesSent").

I will also point out that for writing, you really probably want
IPAddress.HostToNetworkOrder(). After all, you're starting with an int
in "host" order (i.e. stored locally) and sending over the network and
so want it there in "network" order. This hasn't have an effect on
actual outcome; .NET is always little-endian, and network order is
always big-endian, so the bytes get reversed regardless. But the code
would be more maintainable if you used the correct method, to make it
clear which direction the data's going.
I have a specification.

I'm the client.
The customer is the server.
The customer define the telegram. He call this Motorolaformat.
It is working with unsafe, please see my picture again.
http://www1.minpic.de/bild_anzeigen.php?id=79735&key=36633275&ende

I have a bad feeling about my code. That is the reason for my question.

Why we send data with <.NET is always little-endian> ??
Why we send data with <network order is always big-endian> ??

Why we send not so
Client Byte 0, 1, 2, 3, 4, 5, 6, ......1024
0, 0, 0,77,H,e,l,l,o

Do you know the reason?
Do you know advantages?

Greeting Martin
 
B

Ben Voigt [C++ MVP]

Martin Greul said:
Hello Pete,
I have a specification.

I'm the client.
The customer is the server.
The customer define the telegram. He call this Motorolaformat.
It is working with unsafe, please see my picture again.
http://www1.minpic.de/bild_anzeigen.php?id=79735&key=36633275&ende

I have a bad feeling about my code. That is the reason for my question.

Why we send data with <.NET is always little-endian> ??
Why we send data with <network order is always big-endian> ??

Why we send not so
Client Byte 0, 1, 2, 3, 4, 5, 6, ......1024
0, 0, 0,77,H,e,l,l,o

Here is a better way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian.

// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;
Do you know the reason?
Do you know advantages?

Greeting Martin


__________ Information from ESET NOD32 Antivirus, version of virus
signature database 4257 (20090718) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

__________ Information from ESET NOD32 Antivirus, version of virus signature database 4257 (20090718) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com
 
M

Martin Greul

Hello,
Here is a better way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian.

// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;
yes of course, looks simple, instead that.

return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));
But I think Arne has reasons for that. @Arne, can you say something?Do you know the reason for moving the bytes?

Greeting Martin
 
P

Peter Duniho

Here is a better way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian.

// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;

Here is a "better" way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian:

int iT = IPAddress.HostToNetworkOrder(i);

Followed by the same basic thing that would be required in any of the
examples:

writer.Write(iT);

The byte twiddling works, of course. But it's lots more verbose and less
readable. The array-based version even has to create a small temporary
object (the array...of course Arne's version doesn't; his code does
essentially what HostToNetworkOrder() does, just without the method call),
which depending on how it's done could wind up being less readable _and_
less efficient.

The real question here (as I read the OP) isn't even how to swap the byte
order; it's how to write those bytes to the stream, and of course the
BinaryWriter that the OP is already using does that without any additional
effort at all.

Pete
 
P

Peter Duniho

I have a specification.

I'm the client.
The customer is the server.
The customer define the telegram. He call this Motorolaformat.
It is working with unsafe, please see my picture again.
http://www1.minpic.de/bild_anzeigen.php?id=79735&key=36633275&ende

I have a bad feeling about my code. That is the reason for my question.

As I wrote, if you just take out most of the code you posted, you'd be
fine. You're already swapping the bytes (IPAddress.NetworkToHostOrder(),
even if that ought to be the other method), and so all you have to do at
that point is call the BinaryWriter.Write(Int32) overload to write the
resulting int.

All that code that messes with the individual bytes is pointless.
Why we send data with <.NET is always little-endian> ??

I don't understand the question, as it's not grammatically meaningful. If
you're asking why .NET is always little-endian, the short answer is
because that's how Microsoft defined it to be. The slightly longer answer
is that the target platforms are primarily little-endian and so it makes
the compiled code easier to generate.
Why we send data with <network order is always big-endian> ??

Same problem. But if you are asking why network order is always
big-endian, that's also pretty much an arbitrary choice. The truth is
"network order" is only "always big-endian" in certain contexts. It's a
convention followed by networked applications over decades of programming,
but there's actually no requirement that data sent over the network be
transmitted as big-endian. All mainstream protocols that I'm familiar
with follow the big-endian convention, and it's "baked in" to a variety of
network APIs (including various socket APIs), but the only real
requirement is that both ends agree on the byte order.
Why we send not so
Client Byte 0, 1, 2, 3, 4, 5, 6, ......1024
0, 0, 0,77,H,e,l,l,o

What is that example even supposed to demonstrate? "1024" can't even be
fit into a byte, so surely you're not showing bytes? And even if you
were, what about that example is relevant to a question about byte
ordering at all?
Do you know the reason?

The reason for what? If you're asking about byte ordering generally, see
above.
Do you know advantages?

Advantages for what? If you're asking about byte ordering, the main
advantage of making network order big-endian is that that's how everyone
else does it. You'll surprise fewer people by following the existing
convention.

Pete
 
M

Martin Greul

Good morning,
The reason for what? If you're asking about byte ordering generally,
see above.


Advantages for what?
for big or little endian.
Ok it is defined by Microsoft, however.
If you're asking about byte ordering, the main
advantage of making network order big-endian is that that's how everyone
else does it. You'll surprise fewer people by following the existing
convention.
Martin
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
Here is a better way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian.

// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;

Here is a "better" way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian:

int iT = IPAddress.HostToNetworkOrder(i);

Followed by the same basic thing that would be required in any of the
examples:

writer.Write(iT);

The byte twiddling works, of course. But it's lots more verbose and less
readable. The array-based version even has to create a small temporary
object (the array...of course Arne's version doesn't; his code does
essentially what HostToNetworkOrder() does, just without the method call),
which depending on how it's done could wind up being less readable _and_
less efficient.

But he wanted the bytes in an array anyway. So you'd need
HostToNetworkOrder or Arne's version, followed by BitConverter.GetBytes()
 
B

Ben Voigt [C++ MVP]

Martin Greul said:
Hello,
Here is a better way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian.

// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;
yes of course, looks simple, instead that.

return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));
But I think Arne has reasons for that. @Arne, can you say something?Do you know the reason for moving the bytes?

Arne put things back into an Int32, while I put them into a byte array which
I think is what you were asking for.
 
B

Ben Voigt [C++ MVP]

Why we send not so
What is that example even supposed to demonstrate? "1024" can't even be
fit into a byte, so surely you're not showing bytes? And even if you
were, what about that example is relevant to a question about byte
ordering at all?

Evidently the first row is the byte number, location, or "index" if you
will. And the second is the value, with a few missing single quotes.
 
P

Peter Duniho

[...]
The byte twiddling works, of course. But it's lots more verbose and
less readable. The array-based version even has to create a small
temporary object (the array...of course Arne's version doesn't; his
code does essentially what HostToNetworkOrder() does, just without the
method call), which depending on how it's done could wind up being less
readable _and_ less efficient.

But he wanted the bytes in an array anyway.

Um, sort of. If you look at the code he posted, the only thing he uses
the array for is transmitting it. I doubt that he really _needs_ the
bytes in an array; he just did the usual "I've already decided how I
_think_ this problem should be solved, so I'm stating the solution I think
I need, rather than what problem I'm actually trying to solve".

In other words, while he wrote "I want to copy a integer length in a
array", what he really needs to do is send a 32-bit integer -- the data
length -- in big-endian format prior to sending the bytes that are
actually being sent. There's no need at all for that 32-bit integer to be
contained in an array in order to accomplish that.
So you'd need HostToNetworkOrder or Arne's version, followed by
BitConverter.GetBytes()

Not to produce the same output as the code the OP posted, you wouldn't.

Pete
 
P

Peter Duniho

Evidently the first row is the byte number, location, or "index" if you
will. And the second is the value, with a few missing single quotes.

Hmmm. I see what you're saying. But that was an awful way for him to
present that (not the least of which because his first row has 1025 items,
while the second row has -- sort of, if I extrapolate from the byte count,
rather than looking at what's actually written -- only 77 items).

Ah well...thanks for figuring that out. :)
 
A

Arne Vajhøj

Martin said:
Here is a better way which is 100% portable regardless of machine byte
order. Network order is defined as big-endian.

// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;
yes of course, looks simple, instead that.

return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));
But I think Arne has reasons for that. @Arne, can you say something?

I provided that solution as a reply to:

#int lengthInNetworkOrder =
# IPAddress.NetworkToHostOrder(data.Length + 4);
#
#I want to make this function by hand.
#How it is possible?
#Does somebody know the algorithm?
#
#And also for
#
# int lengthInNetworkOrder =
# IPAddress.HostToNetworkOrder(512);


This is int->int.

What you quote above is int->byte[].

Different problem => different code.

Arne
 
M

Martin Greul

Hello,
But he wanted the bytes in an array anyway. So you'd need
HostToNetworkOrder or Arne's version, followed by BitConverter.GetBytes()

ok the final version is from Arne, or?


Have a nice day.


Martin
 
P

Peter Duniho

Hello,

ok the final version is from Arne, or?

That's up to you. What do you _really_ want to do? Do you...

-- ...want to simply transmit a big-endian 32-bit integer ahead of the
bytes? If so, then the code I posted

-- ...want to transmit a big-endian 32-bit integer ahead of the bytes,
but not use IPAddress.HostToNetworkOrder()? If so, then use Arne's code
and just use the BinaryWriter.Write(Int32) overload to send the integer
itself as with my suggestion

-- ...have some specific requirement that the 32-bit integer be
decomposed into bytes and stored in an array? If so, then the code Ben
posted

Unfortunately, you haven't been clear enough about what you're really
trying to do for any of us to know for sure what the right solution is.
But hopefully, with the above guidance, you can figure out for yourself
what the right solution to use is.

Pete
 
M

Martin Greul

Hello,
Unfortunately, you haven't been clear enough about what you're really
trying to do for any of us to know for sure what the right solution is.
But hopefully, with the above guidance, you can figure out for yourself
what the right solution to use is.

I have a solution with unsafe.
http://www1.minpic.de/bild_anzeigen.php?id=79735&key=36633275&ende
But I think is the wrong way.

I will check next week both at customer side.
I hope this is working.

I think, that is better, because I need a array.
// write in big-endian order, regardless of host order
ary[0] = (byte)(i >> 24);
ary[1] = (byte)(i >> 16);
ary[2] = (byte)(i >> 8);
ary[3] = (byte)i;


Here I haven't a array
return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));

I should copy the integer in a array.
How is that possible?

Greeting Martin
 

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