8.   Common Questions

Q: Where can I get those header files?
Q: What do I do when bind() reports "Address already in use"?
Q: How do I get a list of open sockets on the system?
Q: How can I tell if the remote side has closed connection?
Q: How do I build for Windows?
Q: How do I build for Solaris/SunOS? I keep getting linker errors when I try to compile!
Q: Why does select() keep falling out on a signal?
Q: Where can I get those header files?
A: If you don't have them on your system already, you probably don't need them. Check the manual for your particular platform. If you're building for Windows, you only need to #include <winsock.h>.
Q: What do I do when bind() reports "Address already in use"?
A: You have to use setsockopt() with the SO_REUSEADDR option on the listening socket. Check out the section on bind() and the section on select() for an example.
Q: How do I get a list of open sockets on the system?
A: Use the netstat. Check the man page for full details, but you should get some good output just typing:
 
$ netstat

The only trick is determining which socket is associated with which program. :-)

Q: How can I tell if the remote side has closed connection?
A: You can tell because recv() will return 0.
Q: How do I build for Windows?
A: First, delete Windows and install Linux or BSD. };-). No, actually, just see the section on building for Windows in the introduction.
Q: How do I build for Solaris/SunOS? I keep getting linker errors when I try to compile!
A: The linker errors happen because Sun boxes don't automatically compile in the socket libraries. See the section on building for Solaris/SunOS in the introduction for an example of how to do this.
Q: Why does select() keep falling out on a signal?
A: Signals tend to cause blocked system calls to return -1 with errno set to EINTR. When you set up a signal handler with sigaction(), you can set the flag SA_RESTART, which is supposed to restart the system call after it was interrupted.

Naturally, this doesn't always work.

My favorite solution to this involves a goto statement. You know this irritates your professors to no end, so go for it!
 
select_restart:
    if ((err = select(fdmax+1, &readfds, NULL, NULL, NULL)) == -1) {
        if (errno == EINTR) {
            // some signal just interrupted us, so restart
            goto select_restart;
        }
        // handle the real error here:
        perror("select");
    } 

Sure, you don't need to use goto in this case; you can use other structures to control it. But I think the goto statement is actually cleaner.

<<inapoi la documentatie<<