Example programs for a client and server pair demonstrate a case where the client handles data from both the keyboard and the socket open to the server asynchronously. Download the two programs, compile them and get them working. They do nothing useful. Then modify the server to handle connections from two separate clients (not using a fork, just by handling requests from both) asynchronously.
There seem to be a lot of calls and different types of things going on here, but it really isn't that bad. Any socket that wants to do asynchronous IO is handled the same way. This program uses select to handle the IO rather than a signal handler. This is the preferred way to do this in modern operating systems because signal handling is both tricky and relatively high overhead. Note that you do have to define an alternative to the default handling for an IO signal, which is to abort the program. All in all, this process is not as clean as you would like, but that's the way it is.