http://qs321.pair.com?node_id=342866

Jouke has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I want to write two scripts, call them the server and the client, however, since it's intended to run on standalone as well as networked computers, I don't want to communicate over TCP/IP or any other networking protocol for that matter. Another thing involved here is that the primary target Operating System is Windows.
The server is supposed to watch the parallel port (using much of the code of Adremo electrical wheelchair testutility) and whenever it detects a change in the values it reads it should set a flag and allow a client program to see that, and get the value the server just read. The problem is certainly not how to read these values, or how to write a deamon/system tray script. I know how to do this, so please read on.

update: From discussion on the CB it is clear that this posting is a bit too vague. Let me explain a bit better: Currently all scripts I wrote that can be controlled from the mentioned wheelchair all have the same code that checks the parallel port for changes. I want to pull that part of the code out of those scripts and have a server/deamon running that takes care of communicating with the wheelchair. Then (possibly) multiple clients (pVoice, pStory, pShell etcetera) can run and connect to that server and don't have to worry about communicating with the parallel port themselves anymore. However, the values the server reads change very quickly (it may have a certain value for only 1 or 2 cycles (a cycle is about 10ms), that's why I presumed that writing the information to a file wouldn't be fast enough.

The client is a totally seperate script that can be fired up whenever the enduser likes. This script should be able to 'connect' in a certain way to the server and watch the flags the server sets or clears.
I know about signals, pipes and stuff, but I wonder what would be the best way to let those scripts communicate with each other. Writing stuff to a file isn't really an option since that's too slow; the value read from the parallel port may have changed already before the client detects the change.

Does anyone have any experience in writing something like this, without using networking?

Thanks,


Jouke Visser, Perl 'Adept'
Using Perl to help the disabled: pVoice and pStory

Replies are listed 'Best First'.
Re: Communication between seperate scripts
by BrowserUk (Patriarch) on Apr 06, 2004 at 09:45 UTC

    For the standalone scenario, you could look at Win32::DDE though the documentation available seems to be very sparse.

    You could also try the Win32::API route to the API, but then the problem is one of too much documentation. You might be lucky and turn up a simple example somewhere in the web.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
Re: Communication between seperate scripts
by Anonymous Monk on Apr 06, 2004 at 08:48 UTC

    What is wrong with using networking? If you use a TCP connection for example, a client can connect from either another computer on the internet and/or from the same computer. So in the case where it needs to run standalone, you can run both the client and server on the same machine and simply have the client connect to 127.0.0.1 (on the server port). In a networking situation, you just have your client machine connect to the server machine...

      If I'm not mistaking, Windows 98 will try to start Dialup networking when you're trying to connect to any IP address, even localhost...


      Jouke Visser, Perl 'Adept'
      Using Perl to help the disabled: pVoice and pStory
        No-no, you are mistaken. Try it :)
Re: Communication between seperate scripts
by elwarren (Priest) on Apr 06, 2004 at 15:43 UTC
    Shared memory or pipes are going to be your best bets if you want to avoid the network. You can attach several processes to a shared chunk of memory and everyone will see the same data at the same time.

    I previously wrote an app that basically shares a highspeed serial port over the network to another machine. It used UDP for fast communications, no time for lag. Again, this worked on unix and I know that there has been mention of differences in time precision on windows.

    When I researched this project a couple years ago I found several daemons to do port sharing on freshmeat.net. Many of them were written in C and some of them allowed sharing ports between windows and unix machines. There is a standard to do this and these apps had (were supposed to) better signal handling and such. I still ended up using my own because it worked and it was fast and I never had a problem.

    Win32::MMF does the work of this for you. You can either address the memory space as a file or you can tie variables. This is probably what you want to do.

    I haven't done anything with pipes on windows, just unix, can't comment.

    Just checked the perldoc for Win32::MMF and the example shows inter-process signalling. I'd just merge that with your code to read the parallel lines status. Looks like a perfect fit.
      Right. Just what the doctor ordered...now if there was a way to make it work on Win98 machines too, my happiness would be complete :) elwarren++


      Jouke Visser, Perl 'Adept'
      Using Perl to help the disabled: pVoice and pStory
        Somewhat dated, but a good in-depth discussion on Windows MMF can be found here: might come useful should you like to try and add Win98 support to Win32::MMF yourself (not everything can be done, but MMF existed already in Win3.11 IIRC). That will require some 'dirty' work with XS and C, but the module author would probably be willing to help.
        If I were to do it (given my ability with XS) I'd take the local networking path. All you need for the server program is a port to network repeater:
        • a thread reads from the port and writes into some memory buffer (even a perl scalar might do, depends on buffer size); Device-Parallel-Port should probably do what you need (and portably too)
        • another thread answers UDP requests with chunks taken from the shared buffer; regular sockets are all you need
        It could even be done in a single thread, given that both processes should complete pretty fast.
        Hope that's enough to get you started,
        Ant9000
        Cache::FileCache is probably what you're looking for.

        -Nitrox

Re: Communication between seperate scripts
by jfroebe (Parson) on Apr 06, 2004 at 14:47 UTC
    Hi Jouke

    It sounds what you are looking for is a daemon to handle the actual communication. Basically in your scripts, you would pull in a module that knows how to talk to the daemon (sendto_wheelchair, retrieve, etc).

    Unfortunately, in order to avoid using networking, you will have to use windows pipes (NT4, 2k, XP, etc).

    I'm a little leery of using perl for the daemon given the time cycles (this sounds like it will require realtime scheduling) as I'm not sure if you can *consistantly* get the level of granularity out of the script.

    That said, I have a vague memory of someone asking something similar in the microsoft.com newsgroups a couple years back but it was about running Visual Basic applications to interface with a wheelchair. A quick search on google didn't show anything. Thinking that such an daemon might be of use for many people writing applications for the wheelchairs.

    btw, there was a person back in summer that wrote a magazine article about writing perl windows apps for a touch screen display for a disabled family member. For the life of me, I'm unable to remember the name of the magazine.

    now, what you are trying to accomplish is closely tied with anyone performing jobs through a parallel port. You may do well to take a look at the 'hobbyist' angle as well.

    hope this helps

    jason

    No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

Re: Communication between seperate scripts
by didier (Vicar) on Apr 07, 2004 at 06:43 UTC


    You should try Win32::MemMap with Tie::Win32MemMap.
    The first package can be found on the web site of Steve Lidie:
    http://www.lehigh.edu/~sol0/ptk/ptk.html
    Sharing can be done through Tie::Win32MemMap which allows sharing a
    hash between two perl scripts. I don't know where to find this last
    package but I can send it to you on request.

Re: Communication between seperate scripts
by perlsage (Scribe) on Apr 06, 2004 at 12:25 UTC
    You could provide thoroughly readable data in windows registry, this works. Or your "client" machines could write the information to a central machine... Possibilities are almost limitless <;).
      putting data in the registry would work... *BUT* remember that the registry is a fixed size, once that fills up, you will have to extend it while in safe mode. Not an ideal situation. Jouke would be better off using temp files IMHO.

      No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

Re: Communication between seperate scripts
by chanio (Priest) on Apr 07, 2004 at 04:54 UTC
    You might be interested in studying the forking process that popfile does with every module that it finds in the modules folder, in order to keep communication between all of them.

    Just download the multiplatform distribution. And also the schema found at their wiki help file. The writing is very clear, and it is also very well standarized.