Steve
Steve

Reputation: 73

Interfacing with a daemon in C++ with sockets

I'm writing a daemon that needs to both run in the background and take care of tasks and also receive input directly from a frontend. I've been attempting to use sockets to take care of this task, however, I can't get it to work properly since sockets pause the program while waiting for a connection. Is there anyway to get around this?

I'm using the socket wrappers provided at http://linuxgazette.net/issue74/tougher.html

Thank you for any and all help

Upvotes: 3

Views: 2337

Answers (5)

Keith
Keith

Reputation: 6834

Can be worth retaining control of the event loop yourself - its no complicated and provides flexibility down the track.

"C++ pseudo-code" for an event loop.

while (!done)
    {
        bool workDone = false;
        // Loop over each event source or internal worker
        for each module
        {
            // If it has work to do, do some.
            if (module.hasWorkDoTo())
            {
                // Generally, do as little work as possible; e.g. process a single event for this module.
                // But tinker with this to manage priorities if need be.
                // E.g. Maybe allow the GUI to flush its queue.
                module.doSomeWork();
                workDone = true;
            }
        }
        if (!workDone)
        {
            // System idle. No Sleep for a bit so we have benign idle baheviour.
            nanosleep(...);
        }
    }

Upvotes: 0

Usually the daemons use event loops to avoid the problem of waiting for events.

It's the smartest solution to the problem that you present (do not wait to an asynchronous event). ç

Althought, usually the entire daemon is build over the event loop and it's callback architecture, and can cause a partial rewritting, so usually the quick and dirty solution is creating a separate thread to handle those events wich usually creates more bugs than it solves. So, use an event loop:

  • libevent.
  • glib event loop.
  • libev.
  • boost::asio
  • ...

Upvotes: 2

Spaceghost
Spaceghost

Reputation: 6985

From your description, you have already divided your application into a frontend (receiving input) and backend (socket handling and tasks). If the input from the frontend is sent over the socket (via the backend) rather receiving input from the socket then it seems like you are describing a client and not a server. Client programs are typically not implemented as daemons.

You have created a blocking socket and need to either monitor in a separate thread execution a thread or even separate process) or make a non-blocking socket and poll frequently for updates.

The link to the LinuxGazette is a basic intro to network programming. If you would like a little more depth then take a look at Beej's Guide to Network Programming where the various API calls available to you are explained in a little detail.. and will, perhaps, make you appreciate more wrapper libraries such as Boost::ASIO.

Upvotes: 1

Omnifarious
Omnifarious

Reputation: 56048

There are a few ways to handle this problem. This most common is using an event loop and something like libevent. Then you use non-blocking sockets.

Doing this in an event driven fashion can require a big shift in your program logic. But doing it with threads has its own complexities and isn't clearly a better choice.

Upvotes: 2

Karel Petranek
Karel Petranek

Reputation: 15154

You will need to use threads to make the socket operations asynchronous. Or use some library that has already implemented it, one of the top ones is Boost Asio.

Upvotes: 3

Related Questions