I am trying to send over image data from a compiled C++ process to a compiled C# process. The C++ process is accessing the webcam and doing some processing on the image. The image is represented by an 2D array of pixels with each pixel value being an 8 bit value (0-255) which is the gray-scale value of that pixel.
The image size is 640 by 480.
The C# application does some more processing and displays this image onto the screen. The processes are both running at the same time on my laptop (Windows 7 OS) but I cannot make a single process that does all the steps which is why I need my C++ and C# code to communicate.
I was wondering what is the best way to do this? I read about writing a UDP or TCP server in the C# part and a client on the C++ part, I can then send over the image data as a datagram. I was wondering if this is the best way and if it is whether UDP or TCP would be better?
EDIT: The C++ process is unmanaged C++, I don't have the option to run it as a managed DLL. Could I use named pipes to send over the image?
Finally is UDP guaranteed in order if it is communicating locally? I realise the image would be over the limit for UDP but if it is inorder I should be able to split the images up to send over.
Interprocess communication can be done via sockets or pipes.
With sockets(TCP and UDP) you're essentially sending the data over the internet to yourself. Luckily since your comp knows itself, the data shouldn't leave the comp so this should be pretty quick. TCP is guaranteed to be in order and has a bunch of other nice features while UDP is pretty much slap some headers onto the data and hope for the best. For this application TCP should be fine. UDP adds unneeded complexity.
Pipes are the other way to have two processes to communicate. You basically have the C++ or C# process create a pipe and start the other process. You just use the pipe like a file: write to and read from it. This can be done in C/C++ using a combination of the pipe, fork, and exec functions or simply using the popen function. C# probably has similar functions.
I suggest using a pipe using _popen, (popen for windows) and writing a series of ints to the pipe and reading it from the other side. This is probably the easiest way... besides using one language of course...
If you are writing both of the programs, you can compile C++ one as DLL, and call function that returns an array or some structure from your C# program with DllImport Attribute in System.Runtime.InteropServices namespace.
Why can't you do it in the same process? Is it because you need to mix C# and C++? In that case C++/CLI can be used as a bridge between the environments to have both C# code for the .NET CLR and C++ code compiled natively in one process.
If you really need two processes there are several options when running on a local machine, but a small TCP-based service is probably best. The size of each image will be 307kb which is larger than the 65kb limit of UDP.
I was wondering if this is the best way and if it is whether UDP or TCP would be better?
You usually resort to UDP as a speed optimization when TCP is not fast enough and packet loss is inconvenient rather than when it can't be handled. If you can't handle losing part of the image in the transmission I doubt you can resort to UDP.
Moreover, UDP is unlikely to give a performance boost in your case since you'll be using the loopback interface. This means that all TCP packets are likely to arrive in order and without loss, making TCP extra cheap.
If you write your application using TCP and in the future, for some reason, you decide the processes no longer run on the same machine, you won't have to change your code.
Finally, TCP sockets are just easier to use, so unless TCP is not fast enough on your machine, I would stick with TCP sockets.
is UDP guaranteed in order if it is communicating locally?
AFAIK, this behavior is not guaranteed. It is very likely to work most of the time, but unless you can find a quote from relevant documentation, I wouldn't count on this.
Could I use named pipes to send over the image?
Yes, named pipes are very similar to sockets, but they're known to be slow.
Once way of doing it apart from sockets would be to save the image data onto the disk from your C++ application and read it off the disk in your C# application. Of course you will need to make sure some sort of read/write synchronisation so that the file is not read before its fully written.
Or you finally decide to use UDP or TCP, try using RTP. RTP uses UDP with an extra layer of time stamps, sequence numbering to ensure correct order of data delivery. You should be able to find C++ and C# implementations of the protocol. Specifically to mention is that you can send images over a RTP/MJPEG stream if your application is producing JPEG images.
Just move to completely managed code :p (To keep it all in the same process)
https://net7mma.codeplex.com/SourceControl/latest has a C# RtspServer and RtpClient
Related
I have a C# (Mono) app that gets data from a sensor and passes it to a Python script for processing. It runs on a Raspberry Pi/Raspbian. The script is started at program initialization and is running in background waiting for data to be passed to it.
The data consists of 1000 samples, 32 bit double (in total, 32 kbits). Currently I write the data in a file and pass the file path to the script.
I was thinking of speeding up processing time by passing the data directly to the script, avoiding writing the file. However, I see that the number of characters of command line arguments is a limited.
Is there a solution to pass the data to the Python script by avoiding file writing/reading? I've read something about memory mapping, but I do not know if it's a solution.
Writing data to a file relies on the speed of the Micro SDCard used in the raspberry pi. It is good practice to run your program in one application so that all the operation is using the same memory pool.
If not possible, to utilize the RAM you can use communication protocol like MQTT. it is lightweight for Raspberry Pi.
MQTT requires broker (server), and you can start by using mosquitto (http://mosquitto.org/). install it using apt install mosquitto for Raspbian.
In your python and mono source code you can use mqtt client library of your choice. An example of client library is paho-mqtt (https://www.eclipse.org/paho/).
you could also use raw socket but please note that there's maximum data per packet depends on your environment, typically 8KB. https://docs.python.org/3/library/socket.html#socket.socket.recv
Is there a solution to pass the data to the Python script by avoiding
file writing/reading?
I can only think of two approaches:
You could open a socket for communication between both programs through localhost. The C# program would send data to that socket, and the Python program would read it.
Write both programs in Python or C#. The single program would capture
data and process it.
I've read something about memory mapping, but I do not know if it's a
solution.
Memory mapping is about loading a file in memory, and once the work on it is finished, write it back at once. Since you have two different processes, I don't think it is applyable here.
Hope this helps.
I'm adding file sharing capabilities to a basic .NET asynchronous socket server. The payload I'd like clients to send is just my headers+commandID+binaryFileData. This server needs to service requests from VB6 clients in addition to the .NET clients.
The party responsible for the VB6 clients worked out a convoluted way to transfer a file that I'm not particularly impressed by. It involves sending a small block of the file, at the end of which the server asks for the next block. This party claims that the VB6 Winsock control doesn't work well if you try to do a send with a large ("large" means anything not small -- 1MB is "large"). This sounds absurd to me.
I want clients to write a single large payload to the socket, and just do message reassembly/hashing at the server end. Are there actually problems with large writes in VB6 Winsock control, or is the other party making excuses?
No, Winsock and the socket controls have no concept of files or sizes, just a stream of bytes. I expect they're hitting the buffer size in which case they just need to send in chunks until it's all been sent. No need for the server to request the next chunk which will just slow things down.
The claim of VB6 having problems with large (for small values of large) payloads is absolutely true. Even more so, the resulting problems differ from installation to installation and by the phase of the moon. Sending more than a MB to a VB6 winsock control is asking for trouble. Been there, done that, just believe me.
That said, we went down another route: A function would accept a payload of arbitraty size, chunk it up in Megabytes and enqueue it. The winsock control events (SendComplete IIRC) would be used to dequeue the next Megabyte.
This is transparent to the consuming app (a singel call, indifferent of payload size), with the quirks worked around on the sending side - this works reliably without any sophisticated protocol, as the problems are completly inside the client.
I have a device connected to my computer that sends serial data to the computer every 5 mins. I want to write a basic program to capture this serial data every 5 mins and put it into a database. I was hoping to use C# because I have used C# with databases before and found it quite easy.
Can anybody offer me any advice on how I might do this, I really have no idea where to start and I know in theory it sounds easy but when I started it I actually found it really hard.
Using C#, you can use the System.IO.Ports namespace to communicate over the serial ports - there's a nice article here.
Alternatively, you can use Python and the pySerial module. I've written an app to communicate over the serial port using pySerial - it's quite easy to use, and can run on many different operating systems including OSX and Windows (I'm assuming you're using Windows). Python also has built-in support for SQLite.
The problem with capturing data on a serial port is that serial ports aren't thread-safe, so if there is more than one listener, data will be corrupted.
If you are absolutely sure that you're the only one listening for data on this port, .NET has a built-in wrapper, System.IO.Ports.SerialPort, which you can use to connect to COM1, COM2, etc. You'll need to know the rate in bits/sec at which this device sends data (its baud rate), its error-checking (parity) protocol, and the format of the data it is sending (you'll get it as a byte array, which you must convert byte-by-byte into data you can work with). Then, your program should be able to open the port and listen for DataReceived events with a handler that will read and digest the data. Again, it's VERY important that you never have two threads trying to read at once; the easiest way is to set a volatile boolean indicating that a handler is reading data; if another handler is ever spawned while a previous one is still running, the first thing the new one should do is read that value, and since it's set, exit the new handler immediately.
I'm building a network server and starting a lot of AppDomains on the server to which requests are routed. What will be the fastest way to send off a request payload to one of the AppDomains for processing?
Read in the payload from the socket into a byte array and marshal it.
Marshal the network stream (inherits from MarshalByRef) to the AppDomain.
Read the payload. Decode it into objects. Marshal the decoded objects.
Use named pipes to transfer the byte array.
Use loopback sockets.
Maybe there is a way to marshal the actual socket connection?
The decoding mostly creates immutable objects that are used to determine how to fulfill the clients request and the AppDomain then creates a response and marshals it back to the host AppDomain which sends it back through the socket.
The method should prefer less memory over less CPU.
WCF is not an option.
TCP binary remoting is certainly fast, I do not how much faster it is than raw sockets which is probably the fastest, but a royal PIA.
I have run 1500 - 2000 req per second in production using HTTP binary remoting between two boxes. On the same box you should have much high performance using TCP or a name pipes channel, depending in the CPU cycles it takes to process the data.
If I was you I would take a look at how Cassini is implemented. It does pretty much exactly what you are talking about doing.
Actually Cassini has been sort of superceded by Webhost which is the built-in webserver that ships with Visual Studio now. Take a look at this post on Phil Haack's blog for more.
Very good question. If I were coming at this problem I would probably use a Buffered Stream / Memory Stream and marshal the stream into the AppDomain that consumes the object to reduce marshaling or serializing many object graphs that were created in a different AppDomain.
But then again, it sounds like you are almost completely duplicating the functionality of IIS, so I would look/reflector into the System.Web.Hosting namespace and see how they handle it and their WorkerThreadPool etc....
6 .Maybe there is a way to marshal the
actual socket connection?
6-th is IMO the best option.
Socket from process perspective is just a handle. AppDomains reside in single process. That means that appdomains can interchange socket handles.
If socket marshalling is not working, you can try recreating socket in other appdomain. You can use DuplicateAndClose to do this.
If that will not work, you should do some perfomance testing to choose the best data transfer method. (I would choose named pipes or memomry mapped files)
I am building a C# application, using the server-client model, where the server is sending an image (100kb) to the client through a socket every 50ms...
I was using TCP, but besides the overhead of this protocol, sometimes the client ended up with more than one image on the socket. And I still haven't though of a clever mechanism to split the bytes of each image (actually, I just need the most recent one).
I tried using UDP, but got to the conclusion that I can't send 100kb dgrams, only 64kb ones. And even so, I shouldn't use more than 1500bytes; otherwise the packet would be divided along the network and the chances of losing parts of the packet would be greater.
So now I'm a bit confused. Should I continue using TCP and put some escaping bytes in the end of each image so the client can separate them? Or should I use UDP, send dgrams of 1500 bytes and come up with a mechanism for ordering and recovering?
The key goal here is transmitting the images very fast. I don't mind losing some on the way as long as the client keeps receiving newer ones.
Or should I use another protocol? Thanks in advance!
You should consider using Real-time Transport Protocol (aka RTP).
The underlying IP protocol used by RTP is UDP, but it has additional layering to indicate time stamps, sequence order, etc.
RTP is the main media transfer protocol used by VoIP and video-over-IP systems. I'd be quite surprised if you can't find existing C# implementations of the protocol.
Also, if your image files are in JPEG format you should be able to produce an RTP/MJPEG stream. There are quite a few video viewers that already have native support for receiving and displaying such a stream, since some IP webcams output in that format.
First of all, your network might not be able to handle this no matter what you do, but I would go with UDP. You could try splitting up the images into smaller bits, and only display each image if you get all the parts before the next image has arrived.
Also, you could use RTP as others have mentioned, or try UDT. It's a fairly lightweight reliable layer on top of UDP. It should be faster than TCP.
I'd recommend using UDP if:
Your application can cope with an image or small burst of images not getting through,
You can squeeze your images into 65535 bytes.
If you're implementing a video conferencing application then it's worth noting that the majority use UDP.
Otherwise you should use TCP and implement an approach to delimit the images. One suggestoin in that regard is to take a look at the RTP protocol. It's sepcifically designed for carrying real-time data such as VoIP and Video.
Edit: I've looked around quite a few times in the past for a .Net RTP library and apart from wrappers for non .Net libraries or half completed ones I did not have much success. I just had another quick look and this may be of this one ConferenceXP looks a bit more promising.
The other answers cover good options re: UDP or a 'real' protocol like RTP.
However, if you want to stick with TCP, just build yourself a simple 'message' structure to cover your needs. The simplest? length-prefixed. First, send the length of the image as 4 bytes, then send the image itself. Easy enough to write the client and server for.
If the latest is more important than every picture, UDP should be your first choice.
But if you're dealing with frames lager than 64K your have to-do some form of re-framing your self. Don't be concerned with fragmented frames, as you'll have to deal with it or the lower layer will. And you only want completed pictures.
What you will want is some form of encapsulation with timestamps/sequences.