LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-24-2011, 10:15 PM   #1
bt101
Member
 
Registered: Mar 2008
Posts: 61

Rep: Reputation: 19
How Perl IPC Client Server Communication?


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.

Thanks for any help
 
Old 07-25-2011, 11:35 PM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
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.

--- rod.
 
Old 07-26-2011, 06:19 PM   #3
bt101
Member
 
Registered: Mar 2008
Posts: 61

Original Poster
Rep: Reputation: 19
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.
 
Old 07-26-2011, 07:06 PM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
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.

See Beej's Guide to IPC for a good primer and sample code.

--- rod.
 
Old 07-26-2011, 11:22 PM   #5
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by bt101 View Post
...
I've been studying perl IPC/pipes/forks/sockets for days and can't find anything that fits.
...
If both client and server are on the same machine, shared memory is a simple and straightforward way to go.
 
Old 08-06-2011, 11:53 PM   #6
bt101
Member
 
Registered: Mar 2008
Posts: 61

Original Poster
Rep: Reputation: 19
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:
  1. single program looping to do serial communication
  2. 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:
  • Unix domain sockets
  • Internet domain sockets
  • Shared memory
  • Message queues
  • Pipes
  • Named Pipes
  • etc

and their various characteristics:
  • used for related processes
  • used for unrelated processes
  • unidirectional
  • bidirectional
  • speed overhead
  • memory overhead
  • etc
 
Old 08-07-2011, 03:24 AM   #7
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by bt101 View Post
...
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. ...
What is "related processes", "single origin" ? How did you come your conclusion ? I.e. based on what shared memory related manpages ?
 
Old 08-07-2011, 03:38 PM   #8
bt101
Member
 
Registered: Mar 2008
Posts: 61

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by Sergei Steshenko View Post
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:

http://docstore.mik.ua/orelly/perl/cookbook/ch16_13.htm

Notice that the article states "Problem: You want to share variables across forks or between unrelated processes."

I thought... great this is just what I need. Then the solution described is for "related" processes that are forked from a parent???????

So if you know of an example of where they really do share memory between unrelated processes, please let me know.
  • how do they find each other
  • how do they synchronize their activities
  • do they burn cycles while they sit there and check memory
 
Old 08-08-2011, 02:11 AM   #9
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by bt101 View Post
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:

http://docstore.mik.ua/orelly/perl/cookbook/ch16_13.htm

Notice that the article states "Problem: You want to share variables across forks or between unrelated processes."

I thought... great this is just what I need. Then the solution described is for "related" processes that are forked from a parent???????

So if you know of an example of where they really do share memory between unrelated processes, please let me know.
  • how do they find each other
  • how do they synchronize their activities
  • do they burn cycles while they sit there and check memory
Start from http://linux.die.net/man/3/shm_open , http://linux.die.net/man/2/mmap , http://linux.die.net/man/2/mmap2 . If you find in those manpages something on related processes, please let me know.

Yes, you need to do synchronization, and it doesn't burn cycles: http://linux.die.net/man/2/sched_yield , http://linux.die.net/man/3/nanosleep .
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
PPTP Server (client to client communication) disciplefk Linux - Networking 3 06-28-2011 01:39 AM
Please help a problem in client-server ipc message 2 pipes communication ouou Programming 1 06-09-2011 03:26 PM
[SOLVED] Prob: Client/Server Communication zak100 Programming 2 10-18-2010 12:14 PM
Server/Client communication using VM( specifically VirtualBox) Rawan Alhindawi Linux - Newbie 1 12-04-2009 07:22 AM
Server Client communication Kakarot_Rathish Programming 7 01-09-2009 05:40 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:59 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration