[SOLVED] How Perl IPC Client Server Communication?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I need some help with a perl client server app. I don't expect anybody to engineer the thing for me, but I'm lost and just need a push in the eight direction.
I have a bunch of boards connected to a serial port and need separate perl apps to communicate with each board. I can't have all of these apps connect to the one serial port, so I want to write a simple server app that will do all of the serial communication and take requests from client apps to send/receive messages to/from the boards.
Ideally it would look like this in pseudo code:
Server:
Code:
Loop
{
wait forever for message from any client client
send serial
receive serial
send result back to client
}
Client:
Code:
Loop
{
send message to server - wait forever for server to grab message
receive result from server
}
I've been studying perl IPC/pipes/forks/sockets for days and can't find anything that fits. Firstly, every solution seems to be waaaayyyyyy overcomplicated/bloated to just send a few bytes between processes.
The closest I can come is using sockets:
Server:
Code:
bind to a port
loop
{
wait forever for client to connect
get client message
serial send
serial receive
send result to client
close client connection
}
Does the above make sense or is there a better way? Most other examples I see will have each client connection fork an new process and hold-open the connection while the parent loops back to handle more connections. The above process is constantly opening/closing connections and makes clients wait to connect while the server is doing the slow serial communication. Is that bad?
Arggh, even this seems overly bloated to just send a few bytes. There must be a better way.
Your application seems like a fairly typical case for IPC. A socket server that takes connections from a variety of clients makes sense. Depending on the nature of the communications between processes, message queues might also make sense. It is hard to say whether you want to simply signal your serial-talking process with basic small messages, or it you want to stuff whole, arbitrary length messages onto the queue for re-transmittal by the server. If you use a socket-based communication protocol, you probably don't need to close the socket between messages. Just leave it open for as long as your client process runs.
Thanks for the reply.
I'm getting closer as it seems that sockets are the way to go.
Yes, signals would not work as I need to send/receive arbitrary messages (only about 5 or 10 bytes each time).
I would indeed like to leave the connections to the clients open, however I can't see how to do that. My understanding is that the server process cannot both wait for messages from clients *and* wait for new client connections at the same time. In the examples that I have seen, they get around this by having the server program fork new child processes for each client connection. These child processes will wait for messages from the client, while the parent process will loop around to wait for other client connections. Is that the proper way to make a server?
Code:
server parent (waiting for new connections)
client1 <------------> child1
client2 <------------> child2
client3 <------------> child3
I have actually tested the above scenario where the server forks new child processes for each client and it works fine. The clients have no problem having bidirectional communication with the child processes. However, I have no idea where I would put the most important piece of code (the code that does the serial communication). It cannot go in the parent because it is always blocked waiting for new client connections. It cannot go in the child processes because we are back to square-one with many processes that cannot use one serial port. I'm lost.
I should not have used the word 'signal' in the way I did, given it's special meaning in this context. I was using it only in the more general sense, and in the context of passing 'signals' through message queues. By 'signal', I mean a simple, short message which the server can expand by sending an appropriate message on the serial interface. This is in contrast to making the message queues into a full-on communications channel.
Your problem of using sockets goes away if you use message queues. If you use IPC queues, your server can do a blocking read on any message type, where each message type would correspond to a client process (or, all processes could use a common message type, depending on what fits your application). That way, you only have the one server process, and it just loops taking messages out of the queue and acting accordingly. It also makes the potential problem of contesting access to the serial port(s) go away.
Well I had a lot of homework to do.
I'm likely misunderstanding what I've researched but I couldn't figure-out how to make message queues or shared memory work.
As far as I can tell, shared memory if for related processes (single origin). I didn't see a way to make it work with unrelated processes. I also gather that shared memory (while giving the programmer complete control) makes the programmer responsible for synchronization of events.
Message queues seem to be suited for one-way communication. Of course you can do 2-way communication by setting up queues for every client connection. Again, I didn't see an elegant way of doing this.
I ended-up going with the original concept:
Code:
bind to a port
loop
{
wait forever for client to connect
get client message
serial send
serial receive
send result to client
close client connection
}
I made one twist were I used Unix Domain Sockets instead. My understanding that the coding is almost the same as Internet Domain Sockets if I ever want to change it.
So the code is constantly creating/destroying the client connections. As I expected, it adds bloat to the serial communication. I compared these two scenarios:
single program looping to do serial communication
single client looping to do serial communication through server program
The client/server scenario used twice as much CPU and cut the communication rate by 10%. Mercifully serial communication doesn't use much CPU anyway.
I searched the internet for a matrix of how to "narrow" your selection for an IPC method (If I knew what I was doing, I'd publish one). For example, a table which would list the various types of IPC:
What is "related processes", "single origin" ? How did you come your conclusion ? I.e. based on what shared memory related manpages ?
I spent a week looking at all these IPC options so it's all a jumble in my head by now. I couldn't find any example of shared memory between two unrelated processes. The closest I could find was this page:
I spent a week looking at all these IPC options so it's all a jumble in my head by now. I couldn't find any example of shared memory between two unrelated processes. The closest I could find was this page:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.