Setting Up, and Cleaning Up Your Windows Sockets Application

As mentioned earlier, Windows Sockets offers some extensions to the Berkeley sockets paradigm to allow your application to be more "friendly" in the Windows Environment. All such functions are preceded by the characters "WSA", which is short for "Windows Sockets API." Although the use of WSA functions is strongly advised, there are two WSA functions that your application can't avoid: WSAStartup() and WSACleanup().

WSAStartup() "attaches" your application to Windows Sockets and causes the Windows Sockets DLL to initialize any structures that it might need for operation. Additionally, WSAStartup() performs version negotiation and forces an internal Windows Sockets reference count to be incremented. This reference count allows Windows Sockets to maintain the number of applications on the local system requiring Windows Sockets services and structures. The version negotiation allows an application to determine whether or not the underlying Windows Sockets implementation is able to support the same version of the Windows Sockets specification that the application is written to. A Windows Sockets implementation may or may not support multiple versions of the specification. Other Windows Sockets-specific information may also be filled in such as the vendor of the implementation, the maximum datagram size supported, maximum number of sockets which an application can open, and more.

The following startup code is authored to run only under version 1.1 (the most current version of the Windows Sockets specification) or later, and requires that at least six sockets be available to the calling application.


#define    WS_VERSION_REQD    0x0101
#define     WS_VERSION_MAJOR    HIBYTE(WS_VERSION_REQD)
#define     WS_VERSION_MINOR    LOBYTE(WS_VERSION_REQD)
#define    MIN_SOCKETS_REQD    6

WSADATA    wsaData;
char     buf[MAX_BUF_LEN];
int        error;

.
.
.
error=WSAStartup(WS_VERSION_REQUIRED,&wsaData);
if (error !=0 ) {
    /* Report that Windows Sockets did not respond to the WSAStartup() call */

    sprintf(buf,"WINSOCK.DLL not responding.");
    MessageBox (hWnd, buf. "Windows Sockets Error",MB_OK);
    shutdown_app();
}

if (( LOBYTE (wsaData.wVersion) < WS_VERSION_MAJOR) || 
    ( LOBYTE (wsaData.wVersion) == WS_VERSION_MAJOR &&
      HIBYTE (wsaData.wVersion) < WS_VERSION_MINOR)) {

    /* Report that the application requires Windows Sockets version WS_VERSION_REQD */
    /* compliance and that the WINSOCK.DLL on the system does not support it.       */

    sprintf(buf,"Windows Sockets version %d.%d not supported by WINSOCK.DLL",
         LOBYTE (wsaData.wVersion), HIBYTE (wsaData.wVersion));
    MessageBox (hWnd, buf. "Windows Sockets Error",MB_OK);
    shutdown_app();
}

if (wsaData.iMaxSockets < MIN_SOCKETS_REQUIRED ) {
    
    /* Report that WINSOCK.DLL was unable to support the minimum number of  */
     /* sockets (MIN_SOCKETS_REQD) for the application                     */

    sprintf(buf,"This application requires a minimum of %d supported sockets.",
         MIN_SOCKETS_REQUIRED);
    MessageBox (hWnd, buf. "Windows Sockets Error",MB_OK);
    shutdown_app();
}
.

A Windows Sockets application generally callsWSACleanup() during its own cleanup, decrementing the internal reference count and letting Windows Sockets know that it's no longer needed by the calling application. Whatever cleanup this function forces is implementation-specific and shielded from the application. The application author should, however, check for any possible error conditions from WSACleanup() and report them before exiting, as this information might indicate a network layer problem in the system.