This section summarises the content on this page (read on for the full tutorial):
A socket is created for our server connection in an identical manner to that for a client app. Once the socket is open the following steps can be taken:
|IOCTL||Ioctl is used to set non-blocking mode on this socket. This is a first step in disabling “denial of service” (DOS) attacks that purposely do not complete the underlying TCP connection protocols.|
|SETSOCKOPT||The TCP stack does not immediately clean up all connections when an app terminates, most connections enter a timed-wait state and are later deactivated. During this timed-wait it would not be possible to restart the app and listen on the same port again unless we use SetSockOpt to set the REUSE_ADDR option.|
|GETADDRINFO||Rather than hardcoding a port address in the application an app can use a hardcoded service name which as input to GetAddrInfo can be used to obtain the port number on which to listen. This method uses DNS entries to ensure that both client and server use the same protocol version, ip address and port number.|
|BIND||Use the bind API call to define the local endpoint to the TCP stack,
the ip address and port numbers. Typically, a server will accept connection
requests over any of the available network interfaces by specifying a defined
constant INADDR_ANY. An application specific port number is also specified.
This address information must be available to the client apps either as hardcoded values, program parameters or as obtained from a DNS enquiry.
|LISTEN||Listen changes the port status from active to passive, a mode that allows receipt of connection requests from the network. The listen request accepts a backlog parameter which specifies the number of concurrent connection requests that can be handled.|
At this point a multi-connection server app would normally add the socket to select’s monitor list for READ activity and wait for this socket to be notified of a connection attempt. Note that the app needs to flag this socket as a listener, so that select read activity processing can decide whether a receive or an accept request is required.
An alternative for a single connection listener is to issue a blocking accept that waits within the TCP stack for an inbound connection request. This type of server would then typically use the unix spawn function or equivalent to pass the new connection to an independent thread.
No socket create is required as accept performs this implicitly and returns the socket number on completion. The socket number will, however, still need to be added to any bit maps used by select and if necessary, incrementing the max number of sockets.
|ACCEPT||The accept completes TCP’s connection setup and returns the new socket number allocated to this connection. Note that if the connection was not desired the program can issue reject to cancel the TCP connection, this is unusual as there are few criteria on which to base such a decision.|
|At this point the server can have been designed to spawn a new process, in unix like systems, this has the effect of passing the socket to the spawned process and the server process can then close its version of the socket. An alternative is to maintain long running processes that are passed the connection using give_socket. The receiving process is notified by some pre-established inter process communication and issues a take_socket. Of course the socket can also be run on the current process which then processes both listen and receive activities from select.|
|IOCTL||When the process supports multiple connections use Ioctl to set non-blocking mode on this socket.|