Error checking (yuck)
Error checking is very annoying, but it is necessary in a commercial game. Remember that commercial software should be fool-proof and that means a hell of a lot of error checking. How do I check for errors? Most WinSock functions return an int. As a general rule, it is good to say:
if (function(…) == SOCKET_ERROR)
{
cout << "Error!\n";
WSACleanup ();
return;
}
Functions that create or accept sockets usually won't return SOCKET_ERROR, but will return INVALID_SOCKET.
That was basic error checking… Here is the hard part. After SOCKET_ERROR or INVALID_SOCKET, and application should call int WSAGetLastError ( void ). WSAGetLastError will return an error code.
WinSock error codes taken from WSAPI22.DOC:
WinSock code |
Berkeley equivalent |
Error |
Interpretation |
WSAEINTR |
EINTR |
10004 |
As in standard C |
WSAEBADF |
EBADF |
10009 |
As in standard C |
WSAEACCES |
EACCES |
10013 |
As in standard C |
WSAEFAULT |
EFAULT |
10014 |
As in standard C |
WSAEINVAL |
EINVAL |
10022 |
As in standard C |
WSAEMFILE |
EMFILE |
10024 |
As in standard C |
WSAEWOULDBLOCK |
EWOULDBLOCK |
10035 |
As in BSD |
WSAEINPROGRESS |
EINPROGRESS |
10036 |
This error is returned if any WinSock function is called while a blocking function is in progress. |
WSAEALREADY |
EALREADY |
10037 |
As in BSD |
WSAENOTSOCK |
ENOTSOCK |
10038 |
As in BSD |
WSAEDESTADDRREQ |
EDESTADDRREQ |
10039 |
As in BSD |
WSAEMSGSIZE |
EMSGSIZE |
10040 |
As in BSD |
WSAEPROTOTYPE |
EPROTOTYPE |
10041 |
As in BSD |
WSAENOPROTOOPT |
ENOPROTOOPT |
10042 |
As in BSD |
WSAEPROTONOSUPPORT |
EPROTONOSUPPORT |
10043 |
As in BSD |
WSAESOCKTNOSUPPORT |
ESOCKTNOSUPPORT |
10044 |
As in BSD |
WSAEOPNOTSUPP |
EOPNOTSUPP |
10045 |
As in BSD |
WSAEPFNOSUPPORT |
EPFNOSUPPORT |
10046 |
As in BSD |
WSAEAFNOSUPPORT |
EAFNOSUPPORT |
10047 |
As in BSD |
WSAEADDRINUSE |
EADDRINUSE |
10048 |
As in BSD |
WSAEADDRNOTAVAIL |
EADDRNOTAVAIL |
10049 |
As in BSD |
WSAENETDOWN |
ENETDOWN |
10050 |
As in BSD. This error may be reported at any time if the WinSock implementation detects an underlying failure. |
WSAENETUNREACH |
ENETUNREACH |
10051 |
As in BSD |
WSAENETRESET |
ENETRESET |
10052 |
As in BSD |
WSAECONNABORTED |
ECONNABORTED |
10053 |
As in BSD |
WSAECONNRESET |
ECONNRESET |
10054 |
As in BSD |
WSAENOBUFS |
ENOBUFS |
10055 |
As in BSD |
WSAEISCONN |
EISCONN |
10056 |
As in BSD |
WSAENOTCONN |
ENOTCONN |
10057 |
As in BSD |
WSAESHUTDOWN |
ESHUTDOWN |
10058 |
As in BSD |
WSAETOOMANYREFS |
ETOOMANYREFS |
10059 |
As in BSD |
WSAETIMEDOUT |
ETIMEDOUT |
10060 |
As in BSD |
WSAECONNREFUSED |
ECONNREFUSED |
10061 |
As in BSD |
WSAELOOP |
ELOOP |
10062 |
As in BSD |
WSAENAMETOOLONG |
ENAMETOOLONG |
10063 |
As in BSD |
WSAEHOSTDOWN |
EHOSTDOWN |
10064 |
As in BSD |
WSAEHOSTUNREACH |
EHOSTUNREACH |
10065 |
As in BSD |
|
|
Missing 10066 thru 10071 |
|
WSASYSNOTREADY |
|
10091 |
Returned by WSAStartup() indicating that the network subsystem is unusable. |
WSAVERNOTSUPPORTED |
|
10092 |
Returned by WSAStartup() indicating that the WinSock DLL cannot support this app. |
WSANOTINITIALISED |
|
10093 |
Returned by any function except WSAStartup() indicating that a successful WSAStartup() has not yet been performed. |
WSAEDISCON |
|
100101 |
Returned by WSARecv(), WSARecvFrom() to indicate the remote party has initiated a graceful shutdown sequence. |
|
|
Missing 10102 thru 10112 |
|
WSA_OPERATION_ABORTED |
|
* |
An overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl() |
WSAHOST_NOT_FOUND |
HOST_NOT_FOUND |
11001 |
As in BSD. |
WSATRY_AGAIN |
TRY_AGAIN |
11002 |
As in BSD |
WSANO_RECOVERY |
NO_RECOVERY |
11003 |
As in BSD |
WSANO_DATA |
NO_DATA |
11004 |
As in BSD |
To find detailed descriptions of error codes, look at WSAPI22.DOC (Microsoft's WinSock 2.2 API reference). So our fool-proof version looks like this:
if (function(…) == SOCKET_ERROR)
{
cout << "Error:\n";
switch (WSAGetLastError ())
{
case …:
cout << "this type of error happened!\n";
break;
case …
}
WSACleanup ();
cout << "If this error happens again, sue Microsoft!\n";
return;
}
I know it is a real pain in the neck to do all that error checking, but it is necessary.
|