There are a lot of select() tutorials around the net, but most of them do not include much detail on how to correctly handle writing of data to sockets, which can be a pain.
To save you looping through the entire list of connected sockets to check for any data in the output buffer, you can create an FD_SET of all the sockets that have data waiting to be sent out and pass that to select() in addition to your FD_SET of sockets to check for data waiting to be read.
So you could do something like this when you need to send data to a client socket:
fd_set FAR *readfds, // [in, out] Optional pointer to a set of sockets to be checked for readability
fd_set FAR *writefds, // [in, out] Optional pointer to a set of sockets to be checked for writability
fd_set FAR *exceptfds,
const struct timeval FAR *timeout
1) Add the data to the output buffer of the appropriate client.
2) Call a function which tries to send as much of the buffer as possible.
3) If it all sends then, finished.
4) If not, add the socket to your FD_SET of sockets you need to write data to.
5) Pass the FD_SET to select (third paramter).
5) Use the output from select() to know when you can try and write the rest of the data. When you can, goto step 2. Once it's all written. Remove the socket from the FD_SET.
The code around a select statement can become quite complex. I've recently done a lot of research into this subject, so if you need some extra help or just want me to explain this a bit more contact me and I'm sure I'll be able to help out. I might write a guide at some point.