I am connected via ethernet to a simple I/O hardware device which is controlled by a very old, inflexible .NET driver. I've used WireShark to peek at the packets and they are very small, simple packets containing the name of the driver and a few bytes for data (unencrypted). Each packet receives a success packet from the hardware device with a few bytes of confirmation data. There doesn't appear to be any persistence with the connection, it seems to be very trasnsactional.
I would like to fashion my own driver for this device, and send it my own packets to eliminate the junky driver. I understand struct layouts and how to format them explicitly, my question is what the slickest, most modern method of sending data to this network device would be.
Just looking for some info to get me started. Any ideas?
Avoid thinking in terms of "driver", true operating system drivers cannot be written in a .NET language. The original code no doubt used a simple Socket. So can you. The only hard part is figuring out the exact protocol, the meaning of each individual byte.
Use Reflector on the original .NET assembly, you can probably reverse-engineer it. Do first check if your license agreement allows this, it isn't exactly common.
Related
I need to measure as precisely as possible how much of cell service provider's data limit my application uses up.
Is it possible to get the volume of data transferred by a .Net UDP Socket over the network interface (including overhead of UDP and IP)?
The application is a server communicating with a great number of embedded devices, each of which is connected to the internet using GPRS with a very low data limit (several megabytes per month at best, so even a few bytes here and there matter). I know the devices don't open connections with any other servers, so measuring the traffic server-side should be enough.
I know I can't get 100% accurate number (I have no idea what traffic the service provider charges), but I would like to get as close as possible.
Assuming this is IPv4, you could add 28 bytes to every data you transfer but your problem is going to be detecting packet loss and potentially fragmentation. You could add some meta data to your communication to detect packet loss (e.g. sequence numbers, acknowledgments and so on) but that would add more overhead of course which you might not want. Maybe a percentage of expected package loss could help. As for fragmentation again you could compensate when the size of your message is greater than the MTU size (which I believe could be quite small, like 296 bytes, not too sure though, maybe check with your mobile provider)
Another somewhat non-intrusive option could be reading network performance counters of your process or restrict your communication into a separate AppDomain.
Currently I am working on a multi-process desktop application on Windows. This application will be a shrink wrapped application which will be deployed on client machines across the world. While we can have broad specifications for the machines - e.g. Windows XP SP3 with .Net 4.0 CF, we wont have control over them and we cant be too specific on their configuration - e.g. we cannot specify the machine must have a cuda 1.4 capable graphic processor etc.
Some of these processes are managed (.Net 4.0) and others are unmanaged (C++ Win32). The processes need to share data. The options I have evaluated to date are
Tcp sockets
Named Pipes
Pipes seem to perform a little better, but for our needs - performance from both are acceptable. And sockets give us the flexibility of crossing machine (and operating systems - we would like to support non-Microsoft OSes eventually) boundaries in the future hence our preference for going with sockets.
However - my major concern is this - If we use Tcp sockets - are we likely to run into issues with firewalls? Has anyone else deployed desktop applications / programs that use TCP for IPC and experienced issues? If so - what kind?
I know this is a fairly open ended question and I will be glad to rephrase. But I would really like to know what kind of potential problems we are likely to run into.
edit: To throw a little more light - we are only transporting a few PODs, ints, floats and strings. We have built a layer of abstraction that offers 2 paradigms - a request/response and subscription . The transport layer has been abstracted away and currently we have two implementations - pipe based and TCP based.
Performance of pipes is often better on a fast LAN but TCP is often better on slower networks or WANs. See msdn points below.
TPC is also more configurable. Concerning firewalls, they allow you to open/close communication ports. If that's not an option or a concern, an alternative would be http (REST/json, web service, xml rpc, etc...) but you have to consider if the http overhead is acceptable. Make sure you try it with real world datasets (passing trivial data in a test makes the overhead seem unreasonable, which would be very reasonable with a real world data set).
Some other info from msdn:
In a fast local area network (LAN) environment, Transmission Control
Protocol/Internet Protocol (TCP/IP) Sockets and Named Pipes clients
are comparable in terms of performance. However, the performance
difference between the TCP/IP Sockets and Named Pipes clients becomes
apparent with slower networks, such as across wide area networks
(WANs) or dial-up networks. This is because of the different ways the
interprocess communication (IPC) mechanisms communicate between peers.
For named pipes, network communications are typically more
interactive. A peer does not send data until another peer asks for it
using a read command. A network read typically involves a series of
peek named pipes messages before it begins to read the data. These can
be very costly in a slow network and cause excessive network traffic,
which in turn affects other network clients.
It is also important to clarify if you are talking about local pipes
or network pipes. If the server application is running locally on the
computer running an instance of Microsoft® SQL Server™ 2000, the local
Named Pipes protocol is an option. Local named pipes runs in kernel
mode and is extremely fast.
For TCP/IP Sockets, data transmissions are more streamlined and have
less overhead. Data transmissions can also take advantage of TCP/IP
Sockets performance enhancement mechanisms such as windowing, delayed
acknowledgements, and so on, which can be very beneficial in a slow
network. Depending on the type of applications, such performance
differences can be significant.
TCP/IP Sockets also support a backlog queue, which can provide a
limited smoothing effect compared to named pipes that may lead to pipe
busy errors when you are attempting to connect to SQL Server.
> In general, sockets are preferred in a slow LAN, WAN, or dial-up
network, whereas named pipes can be a better choice when network speed
is not the issue, as it offers more functionality, ease of use, and
configuration options.
For more information about TCP/IP, see the Microsoft Windows NT®
documentation.
If you need to impersonate the named pipe client's security credentials, there's really only one option :) And named pipes also have nicer names (although DNS SRV records can provide those for TCP ports also).
Otherwise, there's not much difference. Both treat the data as a stream of bytes, leaving you responsible for finding message boundaries yourself. Named pipes have an additional option of keeping message boundaries for you, but be warned, you must both create the pipe in message mode and explicitly set the read mode as well.
If I correctly understand your requirements you need to communicate between processes running on the same computer. The processes probably run all in the same security context of the user which is logged on interactively.
In the case I should mention that there are different aspects of the solution. One problem is just to share the data between the applications. Another problem is the protocol which defines how the common data could be accessed and modified and how the communication between the processes take place. You can have for example one process which provide the data and all another subscribe the data. Another case: you can have common data which can be read or modified by all the applications and you need just be sure that nobody modify the shared data on the same time or nobody access the data during another modify it. Of cause it could be many other different communication scenarios.
Under the aspect I would suggest you two other options which you don't included in your question:
usage memory mapped files (see here and here)
usage of COM interface
Both ways can be good implemented in both .NET and unmanaged C++. The usage of memory mapped files is the best way from the performance point of view. If you create View which will be not associated with some physical file you will have just common memory which can be used between processes. You can use additionally an Mutex or Event to control that the memory will be not used at the same time by multiple applications.
In the most simple scenario you can even use #pragma data_seg in C++ to place some data in the named section of DLL and use /SECTION option (like /SECTION:.MYSEC,RWS) to make the data shared. You can use the DLL in all your .NET applications and in all unmanaged C++ application to access the common data. In the way you will have simple way to access to the common data.
If you need to have some more complex communication scenario the approach with COM interface in C++/.NET could be the best choice. In case of I would recommend you the article which describes step by step how to implement Primary Interop Assembly with the COM interface only in .NET and uses it in both .NET and C++ COM for the communication.
I just want to listen a network device, capture packets and write the packets to a dummy file. Also i need to filter packets while listening so ill only write packets which passes the filter. I need to do these on .net c#. These are my requirements. So which one should i use? High transfer rate and minimum packet loss is really important.
Thanks for reading.
As the author of SharpPcap I can say that you'll be able to perform all of those operations with the library. Performance was a critical design goal.
Packet.Net has a range of packets that it can parse and is the library bundled along with SharpPcap for packet dissection and generation. It's architecture does lazy evaluation anywhere it is possible in order to be as fast as possible.
Performance is tricky, especially because network packet capture is often a lower priority task for an operating system. The faster your application handles the packet the more packets can be handled without drops. I've been able to capture 3MB/s of packets without any drops. I haven't tried it at higher data rates or written extensive tests to generate and capture data in order to evaluate performance. Tests and real world results are welcome data points to be added to the documentation and website though.
The entire functionality is available in Pcap.Net.
Pcap.Net uses C++/CLI to wrap WinPcap, which is considered more efficient than PInvoke.
The packet library in Pcap.Net is quite big and complex packets can be parsed and created. This includes recursive layers like IP over IP. Parsing of each layer is done lazily and only when you need it.
For your needs, I see only benefits of using Pcap.Net over SharpPcap.
I'm in the process of learning C# and just need a pointing in the right direction. I want to build a client in C# that communicates with a server running PHP/mySQL. There will need to be almost constant communication between the two. It will be for a game, so low-latency and bi-directional communication. I'm not looking for an exact how-to, but rather what method I need to use to connect the two for the fastest and most reliable connection. I have read others use XML, but that seems like it would be slower if used near-constantly, like once or more a second, but I could be totally wrong. Thanks in advance!
Normally communication with those characteristics is made over a persistent TCP connection. C# offers lots of ready-to-use functionality in the System.Net.Sockets namespace (start looking from TcpClient and TcpListener; there are also more low-level interfaces if you need them).
The important question here is: what do you mean exactly "server running PHP"? If the server offers only an HTTP interface, then you would find it more natural to communicate not with sockets but with the WebClient or the more low-level HttpWebRequest classes instead.
Ah, writing a game in C# as a means to get started with the language! How many have started this way.
Have you defined your client-server protocol yet? I'm not talking about TCP vs. UDP, which TomTom and Jon have discussed. I mean, what is the data stream going to look like?
Packet fragmentation is the enemy of low-latency network code. Learn about MTU and packet fragmentation, Nagle's algorithm, etc. and write down some notes for later when you implement the network code. Make sure you calculate the smallest size packet you would be interested in sending, how big its headers might be, and how large of a payload you can fit into that packet. Then see if you can come up with a protocol that uses the available space efficiently.
You may gain a lot more by optimizing your server application and/or porting it to a different language. Just because you CAN use PHP for everything server side doesn't mean you SHOULD. Keep the part that shows you useful information in a web browser, and evaluate whether you should rewrite the time-critical and game client communication parts in another language. Interpreted languages are not especially well known for their speed when crunching real-time game world data. Sure, I once wrote something like that in Perl using POE, but ultimately it was a lot less performant than the C code I was mimicking.
Finally, I would recommend you look into XNA, since it has a lot of this stuff already.
Named Pipes ? XML-RPC ? Standard Input-Output ? Web Services ?
I would not use unsafe stuff like Shared Memory and similar
Named pipes would be the fastest method, but it only works for communication between processes on the same computer. Named pipes communication doesn't go all the way down the network stack (because it only works for communication on the same computer) so it will always be faster.
Anonymous Pipes may only be used on the local machine. However, Named Pipes may traverse the network.
I left out Shared Memory since you specifically mentioned that you don't want to go that route. Shared Memory would be even faster than named pipes tho.
So it depends if you only need to communicate between processes on the same computer or different computers. Any XML-based communication protocol (eg. Web Services) will usually be slower due to the massive overhead in XML.
i don't think there's a quick answer to this. if i was you, i would buy/borrow a copy of Advanced Programming in the Unix Environment (APUE) by Stevens and Rago and read Chapter 15 and 16 on IPC. It's a brilliant book if you really want to understand how *nix (a lot of it applies to any POSIX system) works down to the kernel level.
If you must have a quick answer, i would say the following (without putting a huge amount of thought into it), in descending order of efficiency:
Local Machine IPC
Shared Memory/Memory Mapped
files
Named Pipe/FIFO (only between
related processed - i.e. fork)
Unix Domain Socket
Network IPC/Internet Sockets
Datagram Sockets
Stream Sockets
Raw Sockets
At both levels, you are going to have to think about how the data you transfer is encoded/decoded and trade off between memory usage and CPU utilization.
At the Network level, you will have to consider what layers of protcols you are going to run on top of. Most commonly, at the bottom of the application layer you will be choosing between TCP/IP or UDP. TCP has a lot more overhead as it is does error correction, checksumming and lots of other stuff. if you need in order delivery of messages you need to use TCP as opposed to UDP.
On top of these are other protocols like HTTP, SOAP (on top of HTTP or another protocol like FTP/SMTP etc.). A binary protocol is going to be more efficient as long as you are network bound rather than CPU bound. If using SOAP on the MS.Net platform, then binary encoding of the messages is going to be quicker across the network but may be more CPU intensive.
I could go on. it's not a simple question. Learning where the latencies are and how buffering is handled are key to being able to make decisions on the trade offs you are always forced to with IPC. I'd recommend the APUE book above if you really want to know what is going on under the hood...
Windows Messaging is one of the fastest ways for IPC, after-all Windows is built on them.
It's possible to use WM_COPYDATA with IPInvoke calls to exchange data between 2 form based .Net applications, and I've got an open source library for doing exactly that. I've bench marked around 1771 msg/sec on a fairly hot laptop.
http://thecodeking.github.com/XDMessaging.Net
I don't know why you won't go with shared memory, but its very very fast from C# to C# apps on the same machine, and very reliable (unlike TCP sockets). spazzarama/SharedMemory is a fantastic C# lib that supports shared arrays and buffers with a simple high level API. You just initialize the class with a common memory file name (on client/server sides), and then update the array. Values magically appear on the other side!