I'm deserializing data from a web page generated by php that is using ip2long(). However, when I try to make a new ip address by using the integer value in the constructor of IPAddress the dotted version of the ip address is in reverse order?
ex:
4.3.2.1 should really be 1.2.3.4
Any ideas of how to fix this?
It sounds like someone is using little-endian and someone is using network byte order (big-endian) for the packed value. For instance the octect sequence compromising an integer, AA,BB,CC,DD in LE is DD,CC,BB,AA in BE/NBO -- a nice symmetrical reverse!
Since the IPAddress(Int64) constructor documentations says:
The Int64 value is assumed to be in network byte order.
I would imagine that ip2long in PHP is generating a value in little-endian. Good thing IPAddress also takes byte[] for the constructor, now get those elbows greasy... just pass the bytes in the "correct" order.
Happy coding.
The code at How to convert an int to a little endian byte array? should give some ideas.
Or, as Josh points out, there is a HostToNetworkOrder method to do this.
use long2ip() to reverse the process of ip2long()
<?php
// make sure IPs are valid. also converts a non-complete IP into
// a proper dotted quad as explained below.
$ip = long2ip(ip2long("127.0.0.1")); // "127.0.0.1"
$ip = long2ip(ip2long("10.0.0")); // "10.0.0.0"
$ip = long2ip(ip2long("10.0.256")); // "10.0.1.0"
?>
you shouldn't really have any problems after all it's a standard in php
Related
I have a MOXA Modbus TCP module (M-4210 in combination with the NA-4010 networking module that also has some other modules attached) that works as a 2-channel analog output, each with voltages from 0 to 10 Volts.
In my C# application I need to get the current values of these outputs, which is not as easy as I'm quite new to the whole Modbus thing.
In my code I already have a working modbus tcp client that does its job, I tested it by reading and writing single coils of another digital output module. The analog output module however seems to work with registers instead of coils.
To start from the beginning, these are the modbus settings for the two channels within this module (taken from the MOXA ioAdmin Tool):
and the addresses:
And here's another screenshot from the web interface:
So I tried to read the values like this:
ModbusClient c = new ModbusClient();
c.Connect("172.17.6.15", 502);
int[] r = c.ReadHoldingRegisters(2048, 1);
for (int i = 0; i < r.Length; i++)
{
textBox1.Text += r[i].ToString() + System.Environment.NewLine;
}
This code returns one value, it changed as follows:
When channel #0 is set to the (raw) value of 1139, the returned int value is 29440
When channel #0 is set to 1140, the returned value is 29696
I seem to be on the right track, but I don't quite understand the offsets and how to separate the channels when the value comes back. It would be great if someone could shed some light on this, thanks in advance!
Is your client handling Modbus endianess correctly? Modbus is big endian.
1140 is 0x474, 29696 is 0x7400. 1139 is 0x473, 29440 is 0x7300. I can see a pattern. It seems that your Modbus client is setting the LSB to 0 and taking the MSB by shifting the received LSB to the left.
Try changing the channel's value to 1141, you'll probably read 29952 in your client. That will confirm my suspicion.
Try reading Holding Register 2047 and see if you get the value you're looking for...
Although it seems like the value you're after is shifted by 1 byte, not 2, so you might need to read 2047 and ask for 2 registers and do the shift yourself. Very strange.
How to reassemble TCP packets depending on tcp flags Value:
I'm expecting a code like this:
public void device_onPacketArrival(object sender, CaptureEventArgs e)
{
var tcpPacket=TcpPacket.GetEncapsulated(PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data));
if(tcpPacket.Allflags.toString()== something means that this is the last part of the fragmented packet)
stop reassampling procedure
else
continuing reassembling procedure
}
the only thing that I want is to know what the value of flags means that this is the last part of the fragemented packet?
Because you used %d, which is for decimal integers, instead of %f or %g for doubles.
Because %d is not the format specifier for a double, it's for an int. You should use the correct format string, such as %f.
The format specified "%d" defines an integer NOT a double variable.
Use "%e" or "%g".
Look up the printf format specifiers. %d is for integer values. What you want is probably %f or %e or %g or alike. Have a look at this example:
Example:
#include <stdio.h>
int main() {
double x = 3.141;
printf("%d\n", x);
printf("%e\n", x);
printf("%f\n", x);
printf("%g\n", x);
}
The output is:
$ gcc test.c && /a.out
154573528
3.141000e+00
3.141000
3.141
Note that printf is inherently type unsafe. In above example you see that the output using the integer format specifier is radically different from the others. That is because no conversion is performed, but the byte pattern is directly interpreted as another type, possibly causing invalid memory accesses thereby.
Disclaimer: Note that it's generally less dangerous to use printf then to use a chainsaw. But your mileage may vary if you don't care what end to hold in hands and which one to point at the wood you try to cut. Therefore, you should carefully look out for the documentation of the functions you use.
For reference:
http://en.cppreference.com/w/c/io/fprintf
you can't simply reassemble TCP packets, because its Flags doesn't have more bit or Don't fragment bit IP packet is the only one which has flags like that, so you can only reassemble IP packets using the Flags:
‘Don’t Fragment’ bit. When this bit is set then IP datagram is never fragmented, rather its thrown away if a requirement for fragment arises. The third bit represents the ‘More Fragment’ bit. If this bit is set then it represents a fragmented IP datagram that has more fragments after it. In case of last fragment of an IP datagram this bit is not set signifying that this is the last fragment of a particular IP datagram.
Might have already been said, but since you declared the array variable as a double data-type, you cannot all of a sudden print it using %d which is a data type for an integer. Therefore, I would use the %f or %lf to print it. The aforementioned should work better if you're dealing with double data types
I have the following code in C#:
Console.WriteLine("Connecting to server...");
TcpClient client = new TcpClient("127.0.0.1", 25565);
client.Client.Send(BitConverter.GetBytes(0x02));
client.Client.Send(BitConverter.GetBytes(0x0005));
client.Client.Send(Encoding.UTF8.GetBytes("wedtm"));
Console.Write("{0:x2}", client.GetStream().ReadByte());
For the life of me, I can't figure out how to transpose this to ruby. Any help here?
This is what I have so far, but it's not working as expected:
require 'socket'
s = TCPSocket.open("127.0.0.1", 25565)
s.write(0x02)
s.write(0x0005)
s.write("wedtm".bytes)
response = s.recvfrom(2)
puts "Response Size #{response.size}: #{response.to_s}"
The response should be 0x02
EDIT:
I'm assuming I have to use String#unpack on this, however, I can't figure out how to get "wedtm" to output to the appropriate \x000\x000\x000\x000 format.
There are at least two things to consider here:
Network byte order is big-endian. This means that you should always think in single bytes or arrays of bytes, as bytes are not subject to being shuffled around while larger types are.
C#'s BitConverter.GetBytes(int16) returns 2 bytes in little-endian format and GetBytes(int32) returns 4 bytes in little-endian format
Without knowing any Ruby or its string format, I'd guess you need to do something like this for the first part:
s.write("\x02\x00".bytes)
s.write("\x05\x00\x00\x00".bytes)
The second part should be okay.
WireShark is an invaluable tool when debugging network code and/or reverse engineering networking protocols, record the traffic of the C# app and compare the difference with yours.
What would be the best way to continuously send the mouse position to another computer in C#?
So far I use a TCP socket for transportation. I get the ToString() of MousePosition, convert it to byte[] and send that byte array. On the receiving side I append the bytes to a StringBuilder, parse it and construct a new point. At least it works :-)
I'm new to .net (though I know some Java) and I think there is a better way.
Can one serialize / deserialize a System.Drawing.Point in some (elegant) way? Can one send this serialized object to a remote machine? And if so, how?
Regards
Mike
[;-)
Don't bother with either serialization or strings: just send down the pair of coordinates as integers. You can use BitConverter to convert integers into bytes - or just use BinaryWriter for writing and BinaryReader for reading.
System.Drawing.Point is already marked with <Serializable>, so if you want to, you can use .NET's built in serialization.
I am newbie in Low level programming. In my project(C#.NET) we are using EDBS protocol(7 bit format) for communication and i have the data in bit format to send like 00101010 so we would please guide me how to send these to port.I know that the serial port class accepts data in binary format but dont know how convert the bit format into byte .
Thanks in advance
prem
Use the BitConverter class to create basic types (like bytes or ints) from bytes.
http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx
There is also a class called BitArray that can be used to store bit representations:
Convert from BitArray to Byte
.Net only receives data in byte (the smallest unit), you can use BitConverter to convert various value type to byte of array and vice verse.
There is a class called BitVector32 which lets you encapsulate your bit values into 32 bit number. Sorry about yesterday's answer, I just found this today.