I have Visual C/C++ program which is going to communicate with other Programs(both local and Non-local) over the Intra-net(LAN).Previously I used win32 Memory Mapped Files/Events to communicate locally. Now I want to extend my program to support over network communication.
Since MMF doesn't support network Inter-process communication(term should be Intra-Process Com') it's obvious I have to use Win32 Named Pipes Or WinSock2 mechanisms in order to transferring data through local network.
Here my only intention to build a Intra-network Process communication only, So which mechanism perform better with respect to following factors:
Single Server Multiple Clients - (Duplex -> Transmit & Receive from both end)
Transmit data through slow Local Area Network
Server is basic Visual C/C++ Program and Client end is DLL loaded by another process therefore functionalities should be light-weight.
Transmission Speed (Data should transmit between process with higher frequency)
Which mechanism should be implemented ? Named-Pipes or WinScoket2 ?
Thank you.
Related
I'm trying to make two-way many-to-one communication between programs in Linux.
My plan is the following: One program called "driver" that talks with the hardware needs to communicate with an unknown number of applications in Linux.
I read that one of the most common ways for inter process communication is "named pipes".
The question I haven't found yet is: How new programs should notify the driver that a new program is running so that one more connection (named pipe) between the new program and the driver enstablished?
All programs will be written in C++
In essence, what you've described is a server/client relationship between programs; what each program does on either side of the communications bridge is probably irrelevant.
Even though these processes appear from the question to be intended to be on the same machine, networking is still available to you via localhost.
If you're not wedded to pipes, why not use a port for the driver (server) known to each program (client), to which the server listens?
That's pretty much the underlying philosophy of X-Windows, I believe.
Plus, there should be lots of reliable code out there to get you started.
I also think sockets may be a better solution, but if you really want named pipes, I'd do it this way:
The server opens a pipe named channel_request for reading. Any new client opens it for writing and writes a unique ID. (PID should work). The server reads this id and creates a named pipe called channel_[id]. The client then opens channel_[id] for reading and can start receiving data.
Note that linux pipes are unidirectional, so if you want two-way communications as shown in your diagram, you will need to open both a channel_[id]_out and a channel_[id]_in.
I'm using Visual C++ 2013.
I have two applications (they run on same machine):
The first application receives high quality video streams from multiple clients, synchronizes these videos and writes them to video file (only H264, DIVX and MJPG)
The second application does some processing on each set of synchronized frames in these videos (using OpenCV)
However, I'm get stuck in exchange data between two processes since the read/write task to/from disk is quite slow. So I want to exchange data directly on RAM with low latency and process frame-by-frame.
I've read
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365574%28v=vs.85%29.aspx
but I have no idea dealing with this.
Please help me. Thanks a lot.
There are many ways of doing it. The most simple one is via WM_COPYDATA:
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = 5 * sizeof(WCHAR);
cds.lpData = L"Hello";
::SendMessage(hTargetWnd, WM_COPYDATA, (WPARAM)GetSafeHwnd(), (LPARAM)&cds);
You can easily find your target window handle by calling:
HWND hTargetWnd = ::FindWindow(NULL, L"AppName");
The other method is based on shared memory. If you do use MFC framework there is CSharedFile class that implements this type of IPC.
You can also use UDP sockets for IPC. There are several benefits here:
There is no need to establish connection
The packet loss is almost impossible because the data is transferred via loopback interface.
Again if it is MFC-based app I would use CAsyncSocket class.
I guess that you have a stream of frames that you then distribute to the worker app for processing. I would consider using ZeroMQ for that. Reasons:
ZeroMQ is already message-based, so unlike e.g. TCP (stream-based) or UDP (limited frame size), you can transfer large messages without having to worry about fragmentation.
It manages things like (re-)connecting and some other things that reduce the complexity of your application.
It has a shared memory transport mechanism (you'd have to check if it is supported under MS Windows though) which should be efficient enough for your use cases.
It also supports TCP transport, in case you want to distribute the work to multiple machines.
It has bindings for many languages and for many OSs, in case you want to expand your scope later on.
I’m new to IPC and I’m trying to implement a secure IPC method (not related to encryption).
I’m developing a system in C++ using Visual Studio 2010 (but will be ported to others platforms Linux/MacOS/FreeBSD), this system have a process “A” that needs receive and send a XML to other process “B” on the same computer, but will exist around of 14 process like “B” (B1, B2, ..., B14) that need send/receive a XML to the process “A”.
The process “A” will acts as a proxy/bridge between every process “B”, all data/XML that the process “B” must send, will be sent to the process “A”, and just the process “A” will sends data/XML to the process “B”.
I’m looking for an IPC method to exchange this data between the process “A” and “B1…B14”. The shared memory sounds good to do this, but any process can write/read to the address, so this isn’t secure (I know that is possible to set permission access).
I’m trying to find an IPC method that:
Must be a local only method, I need avoid remote connections.
For security reasons, when a process opens a “channel for communication” to send/receive the data, other process can’t use the same “channel” (unlike shared memory or Boost Message Queue that is possible to write on this channel, or NamedPipe that is possible open other instance with the give name), I want to avoid fake/malicious process. TCP sounds good for this, because isn’t possible that two process listen on the same port (but isn't local only).
3- The process “A” will be a service, and some processes “B” will run as service too and others processes “B” will run as a unprivileged user, so this must not be an administrator-only feature.
4- This project will be code-closed, so I can’t use a code/lib based on the GPL license.
5- If possible, cross-platform (Windows/Linux/MacOS/FreeBSD).
Can someone suggest a suitable IPC technique, either built into the OS or requiring a third-party library?
Short answer:
Windows Pipes for Win32.
Anonymous local sockets for Linux(and family).
Long answer:
On Windows platform there are following commonly used alternatives:
Memory mapped files
Named Pipes
Network sockets (mostly IP)
The unfortunate fact is that none of the above is local-only by nature. Files are shared by storage access, pipes are available due to common RPC/LPC routing and IP is a subject to routing/forwarding configuration (even when using loopback).
I personally recommend using pipes on Win32. They are acting more or less like local sockets on Linux (with some differences though).
On Linux platform:
Shared memory
Pipes
Local sockets (including anonymous ones).
Pipes and local sockets are secure, and in different scenarios each of them have own benefits. As you have multiple client/single server scenario, I would favor local (AF_LOCAL) socket programming. You can either use named sockets (with file-based access control), or anonymous ones. Both options are pretty secure (unless attacker gains local access).
Links
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365780(v=vs.85).aspx
http://manpages.ubuntu.com/manpages/lucid/man7/unix.7.html
write function calls from multiple threads to the same socket
is it safe ?
Do we wanted to add a syncronization among them?
Will it cause fro problems like
Application getting delayed write/read from the Network Layer to Application layer
We are using
GNU C++ libraries
GCC 4 on Linux Redhat Enviornment
This is a Server Side Process where There is only 1 Socket Connectivity between Server & Client Server & Client are on 2 diffent Machines Data is send from Server to Client Client to Server
Problem 1-when Server Send Data to Client Side (Multiple Threads Write data to client Side through the Same Single Socket) But Data Writen from the some of the threads are not gone to client side it doesnot even gone to the network Layer of the same machine (Tcpdump does not have that data)
Problem 2-when Client Send data to Server Data Send By Client is shown in the the server's TCPdump not received for the server application which is reading from the socket from a single thread usinga "read" & "select" functions in a loop
We were unable to identify the pattern of occuring these Problems We think This happend when so many multiple threads are writing to Same socket We are not syncronizationed write function hoping that OS is handling the syncronization
write() is a system call, not a library function, and system calls are generally guaranteed to be atomic.
It is not safe to use write() from multiple threads. There is no guarantee that the output won't be shuffled together. One write could put half of its bytes onto the socket, then another write could start putting it bytes. If you need to be sure each write is written contiguously (and it's hard to imagine not needing that guarantee), then you need a lock or some other synchronization method.
It would be unspecified which write call completes first. A context switch could stall any of the two writes at the first instruction. This can lead to arbitrary ordering. There is nothing write or the kernel can do about that. It is a fundamental problem.
Your data will be written in unspecified order which is probably not acceptable to you.
I would like to write a program and run it on two machines, and send some data from one machine to another in an Ethernet frame.
Typically application data is at layer 7 of the OSI model, is there anything like a kernel restriction or API restriction, that would stop me from writing a program in which I can specify a destination MAC address and have some data sent to that MAC as the Ethernet payload? Then write a program to listen for incoming frames and grab the frames from a specified source MAC address, extracting the payload of data from the frame?
(So I don't want any other overhead like IP or TCP/UDP headers, I don't want to go higher than layer 2).
Can this be done in C++, or must all communication happen at the IP layer, and can this be done on Ubuntu? Extra love for pointing or providing examples! :D
My problem is obviously I'm new to network programming in c++ and as far as I know, if I want to communicate across a network I have to use a socket() call or similar, which works at an IP layer, so can I write a c++ program to work at OSI layer 2, are there APIs for this, does the Linux kernel even allow this?
As you already mentioned sockets, probably you would just like to use a raw socket. Maybe this page with C example code is of some help.
In case you are looking for an idea for a program only using Ethernet while still being useful:
Wake on LAN in it's original form is quite simple. Note however that most current implementations actually send UDP packets (exploiting that the receiver does not parse for packet headers etc. but just a string in the packet's payload).
Also the use of raw sockets is usually restricted to privileged users. You might need to either
call your program as root
or have it owned by root and setuid bit set
or set the capability for creating raw socket using setcap CAP_NET_RAW+ep /path/to/your/program-file
The last option gives more fine grained privileges (just raw sockets, not write access to your whole file system etc.) than the other two. It is still less widely known however, since it is "only" supported from kernel 2.6.24 on (which came with Ubuntu 8.04).
Yes, actually linux has a very nice feature that makes it easy to deal with layer 2 packets. You can use a TAP device, which allows your userspace program to read/write ethernet traffic through the kernel.
http://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/Documentation/networking/tuntap.txt
http://en.wikipedia.org/wiki/TUN/TAP