How to copy a integer length in a array.

P

Peter Duniho

Hello,

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.

Yes, unsafe code is definitely 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;

You say you need an array. But there's nothing in the code you've posted
that shows why you need an array. What are you doing with the array other
than simply transmitting its contents with your BinaryWriter?
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?

See above. You already have code to put the bytes into an array if that's
what you want. It's just not clear that's really what you want.

Until you are specific about what you really need to do, no one else can
suggest what the exact solution is.

Pete
 
M

Martin Greul

Hello,

You say you need an array. But there's nothing in the code you've
posted that shows why you need an array. What are you doing with the
array other than simply transmitting its contents with your BinaryWriter?


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.

You say yes, how is correct? See the picture.

http://www1.minpic.de/bild_anzeigen.php?id=72266&key=56789354&ende

Length of telegram + Message


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);
}

Martin
 
P

Peter Duniho

Hello,




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.

You say yes, how is correct? See the picture.

http://www1.minpic.de/bild_anzeigen.php?id=72266&key=56789354&ende

I looked at the picture. But since I don't read German, the picture
doesn't provide any information that I wasn't already aware of from your
original code.

Here is a version of your method that I believe does exactly what the code
you posted does, but correctly:

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

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

writer.Write(lengthInNetworkOrder);
writer.Write(data);
}

If the above does not address your question, then I think you need a
different strategy for asking your question. I realize that English isn't
your native language. But, that's the language we're using for this
discussion. Everything you've asked has already been answered several
times in English, but you don't seem to comprehend.

If you aren't able to carry on the technical discussion in English (which
would be no embarrassment to you...your English is certainly better than
my German), then you may be better off looking for help from
German-speaking people. You can do that here, by posting in German and
hoping that someone understands it, or by looking for a forum that is
specifically for discussions in German.

I hope we have been able to help, but if not I wish you good luck in
finding your answer from someone who is able to communicate directly in
your preferred language.

Pete
 
B

Ben Voigt [C++ MVP]

Peter said:
Hello,




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.

You say yes, how is correct? See the picture.

http://www1.minpic.de/bild_anzeigen.php?id=72266&key=56789354&ende

I looked at the picture. But since I don't read German, the picture
doesn't provide any information that I wasn't already aware of from
your original code.

Here is a version of your method that I believe does exactly what the
code you posted does, but correctly:

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

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

writer.Write(lengthInNetworkOrder);
writer.Write(data);
}

If the above does not address your question, then I think you need a
different strategy for asking your question. I realize that English
isn't your native language. But, that's the language we're using for
this discussion. Everything you've asked has already been answered
several times in English, but you don't seem to comprehend.

The only difference I can really see is that your solution calls Write twice
and some protocols preserve boundaries. I think a MemoryStream would
overcome that quite easily, or a "gather" write. Of course, I would expect
a method called Write(Int32) to already change the byte order to some
portable endianness, whether it's the network order I have no idea.

And I definitely would not use IPAddress.HostToNetworkOrder on something
that isn't an IP address. IPAddress.HostToNetworkOrder should be
implemented by calling Int32.HostToNetworkOrder (or
Socket.Int32HostToNetworkOrder), not the other way around.
 
B

Ben Voigt [C++ MVP]

Peter said:
I looked at the picture. But since I don't read German, the picture
doesn't provide any information that I wasn't already aware of from
your original code.

Since I do, a little, I'll try to fill in:

"First 4 Bytes -- Length of ???", but clearly referring to the entire packet
including the both message and envelope (containing the length field itself)
Nutzinformation = "User Information"
 
P

Peter Duniho

[...]
The only difference I can really see is that your solution calls Write
twice
and some protocols preserve boundaries.

I'm taking for granted that the variable named "_stream" is in fact a
stream, from a stream-oriented protocol (e.g. TCP), in which case the
write boundaries aren't relevant. I'm especially confident of this
assumption, as you can only create a BinaryWriter instance from a stream.
I think a MemoryStream would
overcome that quite easily, or a "gather" write. Of course, I would
expect
a method called Write(Int32) to already change the byte order to some
portable endianness, whether it's the network order I have no idea.

BinaryWriter.Write(Int32) is documented to use little-endian. Either
little- or big-endian is "portable", of course...so long as everyone has
agreed on the format ahead of time (e.g. the application-level protocol
defines the correct format). But it appears that the OP is dealing with
an app-level protocol that requires big-endian, not little-endian.

Since BinaryWriter.Write(Int32) always sends the given int as
little-endian, it's reliable to simply swap the bytes of the original int
before sending in order to "fool" it into sending the original int as
big-endian.
And I definitely would not use IPAddress.HostToNetworkOrder on something
that isn't an IP address. IPAddress.HostToNetworkOrder should be
implemented by calling Int32.HostToNetworkOrder (or
Socket.Int32HostToNetworkOrder), not the other way around.

I'm not entirely sure I understand your disagreement here is. But, if
you're concerned about the use of something in the IPAddress class rather
than something less specific, sure. The API is perhaps a little awkward.
But, there's a well-established precedent for using the socket API to swap
bytes for networking purposes, even if those bytes aren't specifically for
network addresses. That is, the functions htons() and htonl() (the BSD
equivalents to the HostToNetworkOrder() methods), while existing primarily
so that ports and IP addresses can be byte-swapped, are very often used
for other byte-swapping purposes as well.

I wish .NET had better, more general-purpose endian support. But it
doesn't, and I find it very practical to simply use the built-in support
that does exist, rather than rewriting the exact implementation just so
that you can get a name you like. (Besides, if we're going to get picky
about naming, why are there even two methods -- HostToNetworkOrder() and
NetworkToHostOrder() -- that both do exactly the same thing? Why not just
have an IPAddress.SwapBytes() method?)

Pete
 
M

Martin Greul

Hello,
"First 4 Bytes -- Length of ???", but clearly referring to the entire packet
including the both message and envelope (containing the length field itself)
Nutzinformation = "User Information"
writer.Write(lengthInNetworkOrder);
writer.Write(data);


It is not possible to send two telgrams. The server accept this not.

First 4 Bytes -- Length of the message, (string)


Greeting Martin
 
P

Peter Duniho

Hello,
writer.Write(lengthInNetworkOrder);
writer.Write(data);


It is not possible to send two telgrams. The server accept this not.

You need to define "telgrams". In networking, there's a concept of a
"datagram", but assuming the code you posted is a correct representation
of the code you're actually using, you aren't sending datagrams. You
can't be. If by "telgram" you simply mean a stream of bytes in the format
you're trying to describe (which seems likely), then the fact that the
entire "telgram" isn't sent with a single call to Write() is irrelevant;
it is still a valid "telgram".

As for whether the server does or does not accept this, it had better
accept this. You are using a socket of SocketType.Stream. The semantics
of a stream socket are that data boundaries are not guaranteed to be
preserved. Even if you send all of the data in a single call to
BinaryWriter.Write(), the data may well be sent in any combination of byte
boundaries, with the only guarantee being that the bytes remain in the
original order they were sent, and that byte N won't be sent until bytes 0
through N-1 have been sent.

With a stream socket, you have no control over how the data is actually
sent. Two calls to Write() may be coalesced into a single transmission,
and one call to Write() may be divided into one or more transmissions (the
former being much more likely than the latter -- for short transmissions,
anyway -- but neither being out of the question).

Pete
 
P

Peter Duniho

[...] with the only guarantee being that the bytes remain in the
original order they were sent, and that byte N won't be sent until bytes
0 through N-1 have been sent. [...]

Minor self-nit: actually, what's guaranteed is that byte N won't be
_received_ until bytes 0 through N-1 have been _received_.

Sorry if that caused anyone any confusion.
 

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