views:

233

answers:

3

I want to designate a callback for UDP port such that every time a new packet arrives, a handler is called for it.

I know about using fcntl() to cause file descriptors to raise SIGIO, but let's say things aren't quite that simple. I have an object A with socket a and an object B with socket b. Socket a receives a new packet, and therefore raises a SIGIO. This only affects object A, however, and has nothing to do with object B.

How can I ensure a specific function is called when a specific port receives a packet?

+2  A: 

I recommend using Boost.ASIO library. It is designed for asynchronous I/O.

Cătălin Pitiș
+1  A: 

Boost.Signals or Boost.Signals2 (thread-safe version) may be of use to you.

Ferruccio
+1  A: 

How can I ensure a specific function is called when a specific port receives a packet?

(By "port" here, I assume you metonymously mean the S_IFSOCK file descriptor that represents your UDP socket.)

You have many general options available for I/O-driven apps: blocking reader threads, multiplexing with select(2) or poll(2) or similar, requesting signal notification (esp. using queuing real time signals and extra info in an SA_SIGINFO handler), asynchronous I/O via *aio_read(2)*. See here for a brief overview.

Better yet, use a third party library that abstracts away these messy details, like the elsewhere-mentioned Boost.ASIO or libevent.

Socket a receives a new packet, and therefore raises a SIGIO. This only affects object A, however, and has nothing to do with object B.

Well, not precisely. Signals are delivered to ("handled by") a thread within a process, sometimes a thread of your choosing, and in that sense affect neither object A nor object B directly. :) Do you perhaps mean that a plain SIGIO cannot discriminate "data ready" on socket A from that on socket B?

If so, then don't use a plain SIGIO. Under Linux, fcntl(F_SETSIG) and an SA_SIGINFO handler with real time signals are enough to discriminate one ready fd from another.

pilcrow
However, even if you use F_SETSIG, you still have the problem that you can't do anything of use from within a signal handler without running the risk of crashing horribly. Remember kids, Just Say No to signal handlers.
bdonlan
@bdonlan, I quite agree with your caution, but find your conclusion overly broad. One may quite safely set a *volatile sig_atomic_t* flag or tickle a pipe from with a handler. With careful signal masking, this is all an event- or signal-driven program needs.
pilcrow