My note of socket programming
Extra final note about bind(): there are times when you won’t absolutely have to call it. If you are connect()ing to a remote machine and you don’t care what your local port is (as is the case with telnet where you only care about the remote port), you can simply call connect(), it’ll check to see if the socket is unbound, and will bind() it to an unused local port if necessary.
Socket file descriptor
Someone far away will try to connect() to your machine on a port that you are listen()ing on. Their connection will be queued up waiting to be accept()ed. You call accept() and you tell it to get the pending connection. It’ll return to you a brand new socket file descriptor to use for this single connection! That’s right, suddenly you have two socket file descriptors for the price of one! The original one is still listening on your port and the newly created one is finally ready to send() and recv().
Passing double/int pointer across the wire problem
double d = 3490.15926535;
send(s, &d, sizeof d, 0); /* DANGER–non-portable! */
The receiver gets it like this:
recv(s, &d, sizeof d, 0); /* DANGER–non-portable! */
Fast, simple—what’s not to like? Well, it turns out that not all architectures represent a double (or int) for that matter with the same bit representation or even the same byte ordering! The code is decidedly non-portable.