There are two kinds of errors in Windows Sockets: task-based (or thread-based) and socket-based. An application can retrieve the task-based error by calling WSAGetLastError() immediately after a WinSock function fails (see Chapter 10, "Support Routines," for more information). The socket-based error is:
WSAStartup() is the only function that returns an actual error value, rather than simply indicating an error condition (function failure). This makes sense, since you can't call WSAGetLastError() to retrieve the error value until WSAStartup() succeeds since it will fail with WSANOTINITIALISED (see Chapter 10, "Support Routines," for more information).
Windows Sockets does not support the Berkeley Sockets error variables errno or h_errno, because these per-process global variables don't allow for per-thread error information. The WINSOCK.H header file provides a macro for h_errno for Berkeley source code compatibility (it simply calls WSAGetLastError()). The equivalent macro for errno wasn't included since some applications use errno for non-socket (e.g. file handle) errors.
Most of the error values and their manifest constants (macros) are derived from Berkeley Sockets. The WinSock error values are the BSD error values with a "WinSock API base" error (WSABASEERR) value added to each of them. The macro for each WinSock API error is the equivalent BSD error's macro, with the three letter "WSA" prepended to it. So, for instance, the BSD manifest constant for the "would block" error was defined in the Berkeley Sockets ERRNO.H header file as:
#define EWOULDBLOCK 35
and WINSOCK.H redefines it as:
#define WSAEWOULDBLOCK (WSABASEERR+35)
A few (lower value) WinSock error macro definitions refer to Microsoft C constants. In some cases, these redefine file access errors since Windows NT can treat a socket like a file handle. A few other (higher value) macros are entirely new to Windows Sockets. They refer to error conditions unique to Windows Sockets, such as invalid WinSock version requests, uninitialized WinSock DLL access, or failed hostname resolution attempts.
All of the Windows Sockets error values have macros defined for them in the WINSOCK.H header file. They all have a "WSA" prefix and their values are all biased by the WinSock API base error WSABASEERR (10000) value. The value for WSABASEERR is fairly arbitrary. It's high simply because error values in the Windows API are high values by convention. There is a benefit, though: the unique bias creates identifiable WinSock error values.[Go to Top]
Don't assume the only errors you'll encounter are the ones listed with each function in the WinSock specification. Section 3.3.4 "Error Handling" in the v1.1 Windows Sockets specification warns against this:
"Note that this specification defines a recommended set of error codes, and lists the possible errors which may be returned as a result of each function. It may be the case in some implementations that other Windows Sockets error codes will be returned in addition to those listed, and applications should be prepared to handle errors other than those enumerated under each API description."
The specification is a common denominator among WinSock implementations. The errors it lists don't provide "fine resolution" in all cases, which means it doesn't account for some conditions that some network systems can detect. Finer resolution in error reporting is a double edged sword: with more accurate error values it's easier to diagnose problems when they occur, but it's also more difficult to write an application that can handle all contingencies. The better prepared your application is for any error, the more gracefully you'll handle it, and the easier you'll make your job and the job of your support staff.[Go to Top]
There are two basic types of errors: those an application user can remedy, and those he cannot. As we describe in Chapter 14, "Do's and Don'ts," a user should never see an error that is not user-fixable. If they do, then you need to fix your application to handle the error gracefully. Here is a list of user-fixable errors:
WSAEADDRINUSE (10048) Address already in use
WSAECONNABORTED (10053) Software caused connection abort
WSAECONNREFUSED (10061) Connection refused
WSAECONNRESET (10054) Connection reset by peer
WSAEDESTADDRREQ (10039) Destination address required
WSAEHOSTUNREACH (10065) No route to host
WSAEMFILE (10024) Too many open files
WSAENETDOWN (10050) Network is down
WSAENETRESET (10052) Network dropped connection
WSAENOBUFS (10055) No buffer space available
WSAENETUNREACH (10051) Network is unreachable
WSAETIMEDOUT (10060) Connection timed out
WSAHOST_NOT_FOUND (11001) Host not found
WSASYSNOTREADY (10091) Network sub-system is unavailable
WSANOTINITIALISED (10093) WSAStartup() not performed
WSANO_DATA (11004) Valid name, no data of that type
WSANO_RECOVERY (11003) Non-recoverable query error
WSATRY_AGAIN (11002) Non-authoritative host found
WSAVERNOTSUPPORTED (10092) Wrong WinSock DLL version
Each of these "user-fixable" errors have User suggestions in the detailed error list below. If you want to help your user to help himself as much as possible, then you should pass on some of these suggestions in your error messages. This will avoid support calls. To help yourself when you do get a support call, be sure to include the context of the error in every error message, along with the error value and description (i.e. include the name of the function that caused the error).[Go to Top]