Conversion to Uint16 fails

jnpir

Member
Joined
Apr 14, 2007
Messages
14
Programming Experience
10+
I have some C# code:

private ushort SourcePort;

SourcePort = (
ushort)IPAddress.NetworkToHostOrder(binaryReader.ReadInt16());

Since VB has no ushort type I can use the System.Uint16

Private SourcePort as System.Uint16

SourcePort = Convert.ToUInt16(IPAddress.NetworkToHostOrder(binaryReader.ReadInt16))

A value of -5386 converted to ushort in the above C# is 60151. Thats not larger than the System.Uint16 maximum value. When I convert the same -5386 using the above VB code I get an overflow exception telling me the value is either larger or smaller than what a Uint16 can handle. A Uint16 maximum is 65535

Anyone have some ideas?
 
VB.Net does have both UShort data type and CUShort conversion. Negative Short to UShort overflows for me both in VB.Net and C# (negative is less than the minimum value 0 of unsigned), so .Net doesn't seem to do sign-extending like C++ do (from what I understand), but you can do this math yourself.
 
Doesn't seem possible

I've tried the UShort and CUShort with still no success. I believe the UShort is still derived from the Uint16 structure. With C# ushort types and conversion to the ushort type, it works fine. In VB it seems that the results are unpredictable. I've spent alot of time trying things as well as doing alot of reading on the topic and I think that the most sound solution is to write this logic in C# dll's and then use them in a VB solution. I guess I was just hoping that I could finally do this type of thing in VB. Someday maybe.

Thanks for the reply. If anyone else has a suggestion I'd like to hear it.
 
This conversion fails with C# also (same OverflowException), the code I tested with:
VB.NET:
short s = -5386;
ushort us = (ushort) s;
What do you mean unpredictable exactly? Both the ranges and workaround algoritms are well known (65536+s=60150US). UShort data type is 16bit unsigned integer, represented by the UInt16 structure.

Using other libraries/assemblies with the project is an option if you wish, written in other languages, managed or unmanaged.
 
Heres the details

What I'm doing is reading byte segments from IP, TCP and UDP headers. Some segmants are 1 byte some are 2 and some are 4. I do the read sequentially using a binary reader and memory stream thats passed to the binary reader when a packet is received. Start from the first byte in the header. Thats why I sometimes have binaryReader.ReadInt16, binaryReader.ReadUInt16, binaryReader.ReadUInt32. As per the MSDN:

The NetworkToHostOrder method converts multibyte integer values that are stored on the host system from the byte order used by the network to the byte order used by the host.

Below are just snippets. Obviously I read all the segments as well as any data included in the packets.

I've tried in VB:

Private IPIdentification As UShort

IPIdentification = CUShort(IPAddress.NetworkToHostOrder(binaryReader.ReadInt16))

Fails with divide by zero under certain conditions.

I've tried in VB:

Private UDPDestinationPort As Uint16

UDPDestinationPort = CType(IPAddress.NetworkToHostOrder(binaryReader.ReadInt16), Uint16)

Fails with out of range error.

I've tried in VB:

Private TCPSourcePort As UInt16

Private SourcePort = Convert.ToUInt16(IPAddress.NetworkToHostOrder(binaryReader.ReadInt16))

Fails with out of range error

In C#:

private ushort UDPDestinationPort;

UDPDestinationPort = (ushort)IPAddress.NetworkToHostOrder(binaryReader.ReadInt16());

No matter what segment, this always works. I've run both VB and C# side by side on a receive and when VB fails C# doesn't on the same byte data.
 
Some typos in my last reply

The read is done as follows.

For 1 byte:

binaryreader.ReadByte

For 2 byte:

binary reader.ReadInt16.

For 4 byte:

binaryreader.Int32

No Uints in these calls

Uint16 and Uint32 are in the conversion parts of the calls.

Sorry.
 
Not sure why you are converting the result to unsigned, the NetworkToHostOrder method accept only int16/int32/int64 and returns same type respectively.
 
Does not work without unsigned

Then maybe I'm doing something wrong because I've seen NetwotkToHostOrder return negative values on most all of the segments:

SourcePort,
Destination Port,
SourceAddress,
DestinationAddress,

so on....

Its random. Some packets do, Some don't. When I did some research online I found several similar types of code projects. Most all used unsigned. I suspect thats the reason why. All are done in C#.
 
Probably, signed integers may be negative or positive. Why you want to turn them into unsigned that can only be positive I don't understand.
 
Some more Clarity

Maybe I'm not making it clear:

Private IPDestinationAddress As Int32

IPDestinationAddress = IPAddress.NetworkToHostOrder(binaryReader.ReadInt32)

I've seen IPDestinationAddress as negative value. When I want to display the IP Address:

Public ReadOnly Property DestinationAddress() As IPAddress
Get
Return New IPAddress(IPDestinationAddress)
End Get
End Property

DestinationAddress.ToString

This fails because of Overflow Exception

If you are saying that the NetworkToHostOrder always returns a non negative value, I'm saying I've seen that to be false. That is unless I'm doing something wrong. Every piece of sample code I've seen uses unsigned types to store any of the values returned from NetworkToHostOrder.
 
Not sure why you are converting the result to unsigned, the NetworkToHostOrder method accept only int16/int32/int64 and returns same type respectively.
Probably, signed integers may be negative or positive. Why you want to turn them into unsigned that can only be positive I don't understand.
Maybe you don't know the difference between signed and unsigned integers? Your question indicates that you don't.
 
My comment was in reference to yours:

"
Probably, signed integers may be negative or positive. Why you want to turn them into unsigned that can only be positive I don't understand. "

I thought you were saying that the return from NetworkToHostOrder was only going to be positive. The method returns an Int16/Int32/Int64 which can contain both negative and positive values. I fully understand this and the differences in signed and unsigned. The whole post started because I was unable to convert using UINT16 UINT32 in a reliable manner when in C# this type of thing works 100% of the time. Like I said, I have run both a VB and C# class side by side and processed the same data at the same time. The VB call fails, the C# call does not. The failure in VB is not always. I have to go with what works 100%. Again, every example doing what I need to is written in C, C++ and C#. There are none in VB (at least not what I found)
 
I said unsigned integer can only be positive values, is that hard to understand?

Are you telling that I'm lying in post 4 when I say C# can't convert the negative signed integer to unsigned integer? It throws OverflowException.

Why do you want to cast the signed to unsigned? The algoritm is easy and you already have it, but there doesn't seem to be a reason to do so.
 
Not much else to add

Let me see if I can explain this:

The call:

Dim IPSourceAddress as Int32 = IPAddress.NetworkToHostOrder(binaryReader.ReadInt32)

The call is made to the binaryReader when the reader index is set to the correct position within the IP header. The call works and returns a value.

With the value obtained in the above call, when I do an "x = new IPAddress(IPSourceAddress)" , it fails.

IPAddress accepts 4 byte Array... (Int32) as IPSourceAddress is

The NetworkToHostOrder takes network byte order and swaps it to Host Byte order. If no swap is needed the method does nothing.

When the value returned in the above call:

Dim IPSourceAddress as Int32 = IPAddress.NetworkToHostOrder(binaryReader.ReadInt32)

is done in C# with IPSourceAddress as uint with a conversion to uint

IPSourceAddress = (uint)(binaryReader.ReadInt32());

then the "x=new IPAddress(IPSourceAddress)" works.

So, I tried to do the same thing in VB.

Dim IPSourceAddress as UInt32 = Convert.ToUint32(IPAddress.NetworkToHostOrder(binaryReader.ReadInt32))

I never get to the "x=new IPAddress(IPSourceAddress)" because the call above using the Convert.ToUint32 fails.

When I say fails, I mean that I run a VB and C# class side by side. They both receive the IP Packet at the same time. All values within the packet are identical...Its the same packet. The call to set the value of IPSourceAddress works in C# and fails in VB.
 
No I'm not saying anything about not being truthful. I was saying that when you stated "Probably, signed integers may be negative or positive. Why you want to turn them into unsigned that can only be positive I don't understand", that "that can only be positive I don't understand" was with respect to the NetworkToHostOrder method returning only positive values. So why did I need to convert to unsigned if they were only positive. Sorry for the confusion.

This all started because the conversion to Uint fails in VB. I needed to do the conversion because without it, processing further fails. My reason for doing the conversion is based on all other samples being done in C# doing the conversion and the further processing not failing.

Sorry for the confusion
 
Back
Top