This may be a stupid question, i apologise if it is. But I'm rewriting some c code into c# to use as part of a GUI, the original c programs transmit data buffers backwards and forwards to a microcontroller via:
n = write(sockfd, buf, sizeof(buf));
In the transmitter program and
n = read(sockfd, (void *)buf[idx]+numread,sizeof(buf[0])-numread);
In the receiver program. I am trying to find the c# equivalent of these functions above, but the only one i have found only takes byte data.
The server on the microcontroller runs software i didn't design, hence why i can't simply serialise or convert to byte etc (as in previous similar questions: How to send integer array over a TCP connection in c# and then decompose at the other end, or at least id rather check if theres a solution before i get into trying to edit code i didn't write.
any help greatly appreciated !
You can use NetworkStream.Read/Write to read and write byte arrays to a socket. BinaryReader/Writer are abstractions on top of that that make it easier to write in certain formats.
Related
First of all, what I do at the moment:
I sniff a asyncron serial bus with 9 bit protocol and send the data to the PC. At the PC side I receive the data as an endless string, that looks like that: .12_80E886.02_80E894.13. The Software of the PC-side is written with winforms with C#. Now I have the problem that I haven´t a clearly start you can see it in the stream example. The reason for that is, that I start the sniff somewhere in the protocol.
What I want to do:
I think I can use startindex = IndexOf("_"), and set them now as new start. I have to evaluate sign´s in the stream the stream is build: _(timestamp in milliseconds).(addressbyte databyte). The only what I want to display in my RichTextBox is the databyte, also I need a data management method for the timestamp. Because I have in the GUI the function that I can see the time beetween two or more databyte´s, for that I think I make a sql database. The addressbyte need I to collor the byte with an one as address in a special collor.
Question:
How can I evaluate the stream so that i have alternately timestamp,
addressbyte and than databyte as single substring?
The reason why I want them so, is that, I think I can make an easy if elseif else block to realize all what I want to do.
When someone has an better suggestion for my project pls write it as comment.
With friendly wishes sniffi
I think you're trying to solve two problems at the same time. It would be better to separate them and solve them individually.
There is the issue of transporting the data, for this you are using streams. That is a valid solution. There is sending and receiving the data (bits) over the stream.
You have the problem of transforming these bits (after receiving them) into actual objects (dates, strings, etc..). For that you an use a simple parser, tokenizer, a local script that can get the correct parts from the data and convert it, or you can use a serialization framework (like DataContracts).
If you have simple data, I would opt for using a single method that can parse the data. For more complex scenarios I would look into serialization.
Also be ware that you will need to validate your inputs, since you cannot assume that there is always a trusted (non compromised) piece of software that is sending the bits to you.
I think string is bad choice. Propably data is send as bytes. Sniff rather bytes than string. And you need protocol description to understand data.
You need to read bytes form bus and interpret it.
I have an application in c# which connects to another application, written in c++, via UDP. I'd prefer a performant solution as I am looking to measure the time between an event client-side, some processing server-side and a response of processing complete back on the client-side. Essentially: Round trip delay.
I have an object in c#, for example:
public class Package{
public Package(){}
public float DeliveryTime = 1.5;
public int NumberOfItems = 2
}
I then serialize my package to a byte array:
Package package = new Package();
var serializedPackage = ObjectToByteArray(package);
Next, I send my serializedPackage via UDP (I know, no guarantee of delivery or order, but I don't need those guarantees).
client.Send(serializedPackage , serializedPackage .Length, ip);
My c++ application then received the UDP message...
the question is:
How do I now convert my received byte array back into a usable object with property values maintained?
I need to deserialize into some class Package c++ side and then use the properties... for example some sudo code:
DeserializedPackage deserializedPackage = someDeserializeFunction(bytes);
if(deserializedPackage.NumberOfItems > 0){
cout << deserializedPackage.DeliveryTime;
}
Where do I start? Is this even possible?
I am well versed with C#, but absolutely new to c++, so no mixing c and c++, please. Also, I do not want to use Boost or another library.
I am also open to suggestions such as "convert your package object to JSON and send that. Then deserialize your JSON and populate a c++ object called package."
Your problem is the same, how to serialize types between two languages.
Protocol buffers are one way, here is a similar question about what to do between c++ and java. Google's PBs are suggested there, although there are others.
However, my favorite way to serialize objects in a language agnostic way is JSON. It's easy to reason with and probably the quickest cleanest thing you can implement. So I'd go with that first, unless you have any evidenced performance objection. You seem to already know how to do this?
I have created an app that retrieves network packets using this example: http://www.codeproject.com/Articles/4217/Packet-Sniffing-with-Winpcap-Functions-Ported-to-a
My intention is to use it in order to obtain the content of specific packets sent to a specific application from a server, I'm not interested in any other packets. The packet I'm interesting is 1 value which updates periodically.
I converted it to VB .Net as that is my preference so I'll be giving my code snippets in VB, though I can understand C# as well so feel free to give examples using C#.
It has an event with the parameter 's' which contains the content of the received packet in a byte array.
I'm converting that array to read with a binary reader like this:
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(s)
Dim reader As New System.IO.BinaryReader(stream)
Dim pos As Long = 0
Dim length As Long = reader.BaseStream.Length
I'll then go through a loop with the 'pos' variable as the current position, incremented by the data type of the current bytes. (Like: something = reader.ReadString() pos += something.Length)
My only problem is: I'm not sure what types I should be looking for? What is the 'structure' of a packet? Is it possible to retrieve the server that the packet was sent from, and the application it was sent to?
I've never tried using something like this for packets before, I've only had experience getting data from a custom format database file.
Edit: I've found something a bit more useful which has documentation explaining about source/destination IP and how to filter by them and it looks to be a lot more complete than the above example mentioned earlier.
http://www.codeproject.com/Articles/12458/SharpPcap-A-Packet-Capture-Framework-for-NET
Though it still doesn't give an explanation of how to understand the packet contents itself, but being able to filter the packets is a big help.
There are many different types of possible network packets - most are well documented.
What you'll want to do is download Wireshark (Microsoft also has a similar tool whose name escapes me right now), run some captures with that, and look at the logs.
Wireshark recognizes virtually every existing network packet in existence, so you can use its logs to determine what type of packet you need to be able to recognize and then google for its specification.
Our company makes many embedded devices that communicate with PC's via applications that I write in C#.net. I have been considering different ways of improving the data transfer so that the PC application can be more easily synchronized with the devices current state (which in some cases is continually changing).
I have been thinking about an approach where the device formats it's description and state messages into an xml formatted message before sending them across either the serial port, USB, Ethernet Socket, etc. I was thinking that it may make the process of getting all of this data into my C# classes more simple.
The alternative is an approach where the host application sends a command like GETSTATUS and the device responds with an array of bytes, each representing a different property, sensor reading, etc.
I don't have a great deal of experience with xml but from what I have seen can be done with LINQ to XML it seems like it might be a good idea. What do you guys think? Is this something that is done commonly? Is it a horrible idea?!?
First, which ever way you go, make sure the returned data has a version number embedded so that you can revise the data structure.
Is both an option? Seriously, there are always situations where sending data in a more readable form are preferable, and others where a more dense representation is best (these are fewer than most people think, but I don't want to start a religious war about it). People will passionately argue for both, because they are optimizing for different things. Providing both options would satisfy both camps.
A nice, clear XML status could definitely lower the bar for people who are starting to work with your devices. You could also build a C# object that can be deserialized from the binary data that is returned.
It isn't a terrible idea, but it is probably an overdedesign. I would prefer to use a format that the embedded device will generate easier and faster. Then at the PC side I would insert a layer to conver it to a convenient format. You can also use LINQ with objects. Why don't send the data in binary form or in a simple ASCII protocol and then convert it to C# objects? You can use LINQ to access the data. In my opinion, in this case XML introduces an unnecessary complexity.
There are tradeoffs either way, so the right choice depends on your application, how powerful your device is and who is going to be using this protocol.
You mention that the alternative is a binary-serialized, request-response approach. I think that there are two separate dimensions here: the serialization format (binary or XML) and the communication style. You can use whatever serialization format you want in either a push protocol or in a request-response protocol.
XML might be a good choice if
Readability is important
If there is variation between devices, i.e. if you have different devices that have different properties, since XML tends to be self-describing.
Or if you want to publish your device's data to the Internet.
Of course, XML is verbose and there are certainly ways to accomplish all of the above with a binary protocol (e.g. with tagged values can be used to make your binary protocol more descriptive).
One of the founders of this very site has some sane and amusing opinions on XML in XML: The Angle Bracket Tax
I did something very similar in a previous design with PC to microprocessor communications using an XML format. It worked very well on the PC side since what Adobe Flex (what we were using) could interpret XML very easily, and I suspect .Net can do the same thing very easily.
The more complicated part of it was on the microprocessor side. The XML parsing had to be done manually, which was not really that complicated, but just time intensive. Creating the XML string can also be quite a lot of code depending on what you're doing.
Overall - If I had to do it again, I still think XML was a good choice because it is a very flexible protocol. RAM was not that much of an issue with regards to storing a few packets in our FIFO buffer on the microprocessor side but that may be something to consider in your application.
It's a waste of precious embedded CPU time to generate and transmit XML files. Instead, I would just use an array of binary bytes represent the data, but I would use structs to help interpret the data. The struct feature of C# lets you easily interpret an array of bytes as meaningful data. Here's an example:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DeviceStatus
{
public UInt16 position; // Byte 0 and 1
public Byte counter; // Byte 2
public Fruit currentFruit; // Byte 3
};
enum Fruit : Byte
{
Off = 0,
Apple = 1,
Orange = 2,
Banana = 3,
}
Then you would have a function that converts your array of bytes to this struct:
public unsafe DeviceStatus getStatus()
{
byte[] dataFromDevice = fetchStatusFromDevice();
fixed (byte* pointer = dataFromDevice)
{
return *(DeviceStatus*)pointer;
}
}
Compared to XML, this method will save CPU time on the device and on the PC, and it is easier to maintain than an XML schema, with complementary functions for building and parsing the XML file. All you have to do is make sure that the struct and enum definitions in your embdedded device are the same as the definitions in your C# code, so that the C# program and device agree on the protocol to use.
You'll probably want to use the "packed" attribute on both the C# and embedded side so that all the struct elements are positioned in a predictable way.
First of all i am new to networking so i may say dumb thing in here.
Considering a client-server application using sockets(.net with c# if that matters).
The client sends some data, the
server process it and sends back a
string.
The client sends some other data,
the serve process it, queries the db
and sends back several hundreds of
items from the database
The client sends some other type of
data and the server notifies some
other clients
.
My question is how to set the buffer size correctly for reading/writing operation.
Should i do something like this: byte[] buff = new byte[client.ReceiveBufferSize] ?
I am thinking of something like this:
Client sends data to the server(and the server will follow the same pattern)
byte[] bytesToSend=new byte[2048] //2048 to be standard for any command send by the client
bytes 0..1 ->command type
bytes 1..2047 ->command parameters
byte[] bytesToReceive=new byte[8]/byte[64]/byte[8192] //switch(command type)
But..what is happening when a client is notified by the server without sending data?
What is the correct way to accomplish what i am trying to do?
Thanks for reading.
Doesn't matter what is the size of your buffer, it should be just a temporary storage for the data. Read this about reading from binary streams: http://www.yoda.arachsys.com/csharp/readbinary.html
I don't really understand what you are trying to do, but i try to give some advice. Your byte array and the Socket.ReceiveBufferSize property are two different things. The buffer size doesn't matter. You should use a byte array large enough to store the data you want to send or receive. For the size of the byte array, 2048 is probably ok, unless you want to send images, very large text, etc. I've done some simple client server programming and i found it easier if the receiver knows how much data to receive in advance. So for example you send the length of the string first as 1 or 2 bytes, and then the string using utf8 encoding. Use the Encoding.GetByteCount method for getting the size of the string in bytes for the chosen encoding. You should convert numbers to binary using the methods from Bitconverter. I found those helpful and now i wish, i would have discovered them earlier. To send other more complex data types you should decompose them and send them as strings or numbers one at a time.
When designing client/server communication it is good to introduces some a notion of a communication protocol (basically a set of rules, format that will be sent/received) by the client/server.
Here's an example of exchanging messages of variable size over the network
You can simplest think about XML as a protocol of your communication, then you reading socket until null byte was readed. (This is typicaly marker of end of xml document). You can implement this protocol in two ways.
To parse and generate XML document you can use XMLDocument class. You must to it impelemnt some schema. But if you want clean transform data as XML you can use simplest DataSet.