1Waiting on a socket
Shows how to wait for traffic on the socket instead of polling. This is mainly useful when running under an operating system instead of directly on the metel.
We wait by having the main loop ask for the active sockets so we can use select() or one of the other handles.
Files
FileServer.c
The file server is setup to just send a basic page as this example works mainly in the main.c file.
main.c
The main has it's main loop changed to wait on the sockets that the web server currently have open.
First there are some new variables:
- OSHandles
- rfds
- retval
- MaxFD
- r
- HandleCount
OSHandles[] is used to hold the socket handles that are currently open. This has the same number as WS_OPT_MAX_CONNECTIONS plus one for the listening socket. We will fill this array in by calling WS_GetOSSocketHandles().
rfds is the set of OS handles to wait on. This is filled in using FD_SET() with each the socket handles that where returned in OSHandles[].
retval is the return value from the select() it's self. We only print out an error if select() returns an error
MaxFD is the highest OS file handle that we found in the socket handles.
r is just a simple loop counter.
HandleCount is the number of socket handles that was returned by WS_GetOSSocketHandles().
This all remains unchanged
We have replaced the usleep(1000); with code to get the active sockets and then wait on them.
The first thing we do is normal select() handing such has zeroing the rfds variable.
We then call WS_GetOSSocketHandles() to get the active sockets. This will fill in the OSHandles[] array with the socket handles we will waiting on. The web server may have up to WS_OPT_MAX_CONNECTIONS open, or none of them (depending on what requests are being processed) the WS_GetOSSocketHandles() function returns the number of handles it filled in.
WS_GetOSSocketHandles() uses t_ConSocketHandle as the type data for a OS socket handle. This type will depend on what a socket handle on the OS being used is. This is defined in SocketsCon.h. This allows the system to return a complex type such as a structure as a socket handle.
In this example it is a Unix style handle which is a simple int.
Next we need to find the highest socket handle number to pass into select(). We loop through all the handles returned to us updating MaxFD if the new handle is bigger than the old MaxFD. We also need to use FD_SET() to setup rfds.
At this point we call the select that will wait forever for something to happen on one of the sockets.
If the return value from select() is negative then we just print an error message and continue. You would likely want to handle the error here.
The shut down code remains the same as before.