Platform_Win32_Network.cpp
Go to the documentation of this file.00001 //*** Platform_Win32_Network.cpp *** 00002 00003 #define WIN32_LEAN_AND_MEAN 00004 #define VC_EXTRALEAN 00005 #include <winsock2.h> 00006 00007 #include "Platform_Win32_Network.h" 00008 #include "Platform_Win32_Network_Server.h" 00009 #include "Platform_Win32_Network_Client.h" 00010 #include "Debug.h" 00011 #include "ArrayIterator.h" 00012 00013 #pragma comment (lib, "Ws2_32.lib") 00014 00015 00016 00017 //*** Constructor *** 00018 00019 Platform_Win32_Network::Platform_Win32_Network() 00020 { 00021 Platform::RegisterEventListener(this); 00022 00023 networkingEnabled_=false; 00024 usingWinsock2_=false; 00025 00026 00027 WSADATA wsaData; 00028 00029 // Initialize Winsock. Try the highest version first, then fall back 00030 // to older and older versions until we get one which works 00031 if (WSAStartup(MAKEWORD(2,2), &wsaData)==0) 00032 { 00033 // Found Winsock 2.2 00034 DebugPrint(("WSAStartup - Using Winsock 2.2\n")); 00035 networkingEnabled_=true; 00036 usingWinsock2_=true; 00037 } 00038 else if (WSAStartup(MAKEWORD(2,1), &wsaData)==0) 00039 { 00040 // Found Winsock 2.1 00041 DebugPrint(("WSAStartup - Using Winsock 2.1\n")); 00042 networkingEnabled_=true; 00043 usingWinsock2_=true; 00044 } 00045 else if (WSAStartup(MAKEWORD(2,0), &wsaData)==0) 00046 { 00047 // Found Winsock 2.0 00048 DebugPrint(("WSAStartup - Using Winsock 2.0\n")); 00049 networkingEnabled_=true; 00050 usingWinsock2_=true; 00051 } 00052 else if (WSAStartup(MAKEWORD(1,1), &wsaData)==0) 00053 { 00054 // Found Winsock 1.1 00055 DebugPrint(("WSAStartup - Using Winsock 1.1\n")); 00056 networkingEnabled_=true; 00057 usingWinsock2_=false; 00058 } 00059 else if (WSAStartup(MAKEWORD(1,0), &wsaData)==0) 00060 { 00061 // Found Winsock 1.0 00062 DebugPrint(("WSAStartup - Using Winsock 1.0\n")); 00063 networkingEnabled_=true; 00064 usingWinsock2_=false; 00065 } 00066 else 00067 { 00068 // WSAStartup failed, no winsock available 00069 DebugPrint(("WSAStartup - FAILED\n")); 00070 DebugPrint(("Networking not available\n")); 00071 networkingEnabled_=false; 00072 usingWinsock2_=false; 00073 return; 00074 } 00075 00076 } 00077 00078 00079 //*** Destructor *** 00080 00081 Platform_Win32_Network::~Platform_Win32_Network() 00082 { 00083 for (int i=0; i<clients_.GetItemCount(); i++) 00084 { 00085 clients_.Get(i)->Disconnect(); 00086 } 00087 00088 for (int i=0; i<servers_.GetItemCount(); i++) 00089 { 00090 servers_.Get(i)->Disconnect(); 00091 } 00092 00093 // Shutdown Winsock 00094 if (WSACleanup()==0) 00095 { 00096 DebugPrint(("WSACleanup done\n")); 00097 } 00098 else 00099 { 00100 DebugPrint(("WSACleanup FAILED\n")); 00101 } 00102 00103 00104 Platform::UnregisterEventListener(this); 00105 } 00106 00107 00108 00109 //*** OnOsYield *** 00110 00111 void Platform_Win32_Network::OnOsYield() 00112 { 00113 for (int i=0; i<servers_.GetItemCount(); i++) 00114 { 00115 servers_.Get(i)->Update(); 00116 } 00117 00118 for (int i=0; i<clients_.GetItemCount(); i++) 00119 { 00120 clients_.Get(i)->Update(); 00121 } 00122 } 00123 00124 00125 //*** IsNetworkingEnabled *** 00126 00127 bool Platform_Win32_Network::IsNetworkingEnabled() 00128 { 00129 return networkingEnabled_; 00130 } 00131 00132 00133 //*** UsingWinsock2 *** 00134 00135 bool Platform_Win32_Network::UsingWinsock2() 00136 { 00137 return usingWinsock2_; 00138 } 00139 00140 00141 //*** DisableNetworking *** 00142 00143 void Platform_Win32_Network::DisableNetworking() 00144 { 00145 DebugPrint(("An error occured in Winsock - Networking is disabled")); 00146 networkingEnabled_=false; 00147 usingWinsock2_=false; 00148 } 00149 00150 00151 //*** ClientDestroyed *** 00152 00153 void Platform_Win32_Network::ClientDestroyed(Platform_Win32_Network_Client* client) 00154 { 00155 ArrayIterator<Platform_Win32_Network_Client*> it(clients_); 00156 if (it.Find(client)) 00157 { 00158 clients_.Remove(it); 00159 } 00160 } 00161 00162 00163 //*** ServerDestroyed *** 00164 00165 void Platform_Win32_Network::ServerDestroyed(Platform_Win32_Network_Server* server) 00166 { 00167 ArrayIterator<Platform_Win32_Network_Server*> it(servers_); 00168 if (it.Find(server)) 00169 { 00170 servers_.Remove(it); 00171 } 00172 } 00173 00174 00175 //*** CreateServer *** 00176 00177 Platform_Network_Server* Platform_Win32_Network::CreateServer(ConnectionMode mode, int port) 00178 { 00179 // Check to make sure networking is available 00180 if (!networkingEnabled_) 00181 { 00182 return 0; 00183 } 00184 00185 // Create the connection 00186 Platform_Win32_Network_Server* server=new Platform_Win32_Network_Server(this,mode,port); 00187 00188 // Add the connection to the list of active clients 00189 servers_.Add(server); 00190 00191 // Return the connection 00192 return server; 00193 } 00194 00195 00196 //*** CreateClient *** 00197 00198 Platform_Network_Client* Platform_Win32_Network::CreateClient(ConnectionMode mode, const char* address, int port) 00199 { 00200 // Check to make sure networking is available 00201 if (!networkingEnabled_) 00202 { 00203 return 0; 00204 } 00205 00206 // Create the connection 00207 Platform_Win32_Network_Client* client=new Platform_Win32_Network_Client(this,mode,address,port); 00208 00209 // Add the connection to the list of active clients 00210 clients_.Add(client); 00211 00212 // Return the connection 00213 return client; 00214 } 00215 00216 00217 //*** GetErrorMessage *** 00218 00219 const char* Platform_Win32_Network::GetErrorMessage(unsigned int errorCode) 00220 { 00221 // Define all error messages as an array of unnamed structs, mapping error code to error message 00222 struct 00223 { 00224 unsigned int errorCode; 00225 const char* errorMessage; 00226 } errorTexts[] = 00227 { 00228 { WSAEINTR, "A blocking operation was interrupted by a call to WSACancelBlockingCall.." }, 00229 { WSAEBADF, "The file handle supplied is not valid." }, 00230 { WSAEACCES, "An attempt was made to access a socket in a way forbidden by its access permissions." }, 00231 { WSAEFAULT, "The system detected an invalid pointer address in attempting to use a pointer argument in a call." }, 00232 { WSAEINVAL, "An invalid argument was supplied." }, 00233 { WSAEMFILE, "Too many open sockets." }, 00234 { WSAEWOULDBLOCK, "A non-blocking socket operation could not be completed immediately." }, 00235 { WSAEINPROGRESS, "A blocking operation is currently executing." }, 00236 { WSAEALREADY, "An operation was attempted on a non-blocking socket that already had an operation in progress." }, 00237 { WSAENOTSOCK, "An operation was attempted on something that is not a socket." }, 00238 { WSAEDESTADDRREQ, "A required address was omitted from an operation on a socket." }, 00239 { WSAEMSGSIZE, "A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself." }, 00240 { WSAEPROTOTYPE, "A protocol was specified in the socket function call that does not support the semantics of the socket type requested." }, 00241 { WSAENOPROTOOPT, "An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call." }, 00242 { WSAEPROTONOSUPPORT, "The requested protocol has not been configured into the system, or no implementation for it exists." }, 00243 { WSAESOCKTNOSUPPORT, "The support for the specified socket type does not exist in this address family." }, 00244 { WSAEOPNOTSUPP, "The attempted operation is not supported for the type of object referenced." }, 00245 { WSAEPFNOSUPPORT, "The protocol family has not been configured into the system or no implementation for it exists." }, 00246 { WSAEAFNOSUPPORT, "An address incompatible with the requested protocol was used." }, 00247 { WSAEADDRINUSE, "Only one usage of each socket address (protocol/network address/port) is normally permitted." }, 00248 { WSAEADDRNOTAVAIL, "The requested address is not valid in its context." }, 00249 { WSAENETDOWN, "A socket operation encountered a dead network." }, 00250 { WSAENETUNREACH, "A socket operation was attempted to an unreachable network." }, 00251 { WSAENETRESET, "The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress." }, 00252 { WSAECONNABORTED, "An established connection was aborted by the software in your host machine." }, 00253 { WSAECONNRESET, "An existing connection was forcibly closed by the remote host." }, 00254 { WSAENOBUFS, "An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full." }, 00255 { WSAEISCONN, "A connect request was made on an already connected socket." }, 00256 { WSAENOTCONN, "A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied." }, 00257 { WSAESHUTDOWN, "A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call." }, 00258 { WSAETOOMANYREFS, "Too many references to some kernel object." }, 00259 { WSAETIMEDOUT, "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." }, 00260 { WSAECONNREFUSED, "No connection could be made because the target machine actively refused it." }, 00261 { WSAELOOP, "Cannot translate name." }, 00262 { WSAENAMETOOLONG, "Name component or name was too long." }, 00263 { WSAEHOSTDOWN, "A socket operation failed because the destination host was down." }, 00264 { WSAEHOSTUNREACH, "A socket operation was attempted to an unreachable host." }, 00265 { WSAENOTEMPTY, "Cannot remove a directory that is not empty." }, 00266 { WSAEPROCLIM, "A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously." }, 00267 { WSAEUSERS, "Ran out of quota." }, 00268 { WSAEDQUOT, "Ran out of disk quota." }, 00269 { WSAESTALE, "File handle reference is no longer available." }, 00270 { WSAEREMOTE, "Item is not available locally." }, 00271 { WSASYSNOTREADY, "WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable." }, 00272 { WSAVERNOTSUPPORTED, "The Windows Sockets version requested is not supported." }, 00273 { WSANOTINITIALISED, "Either the application has not called WSAStartup, or WSAStartup failed." }, 00274 { WSAEDISCON, "Returned by WSARecv or WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence." }, 00275 { WSAENOMORE, "No more results can be returned by WSALookupServiceNext." }, 00276 { WSAECANCELLED, "A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled." }, 00277 { WSAEINVALIDPROCTABLE, "The procedure call table is invalid." }, 00278 { WSAEINVALIDPROVIDER, "The requested service provider is invalid." }, 00279 { WSAEPROVIDERFAILEDINIT, "The requested service provider could not be loaded or initialized." }, 00280 { WSASYSCALLFAILURE, "A system call that should never fail has failed." }, 00281 { WSASERVICE_NOT_FOUND, "No such service is known. The service cannot be found in the specified name space." }, 00282 { WSATYPE_NOT_FOUND, "The specified class was not found." }, 00283 { WSA_E_NO_MORE, "No more results can be returned by WSALookupServiceNext." }, 00284 { WSA_E_CANCELLED, "A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled." }, 00285 { WSAEREFUSED, "A database query failed because it was actively refused." }, 00286 { WSAHOST_NOT_FOUND, "No such host is known." }, 00287 { WSATRY_AGAIN, "This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server." }, 00288 { WSANO_RECOVERY, "A non-recoverable error occurred during a database lookup." }, 00289 { WSANO_DATA, "The requested name is valid, but no data of the requested type was found." }, 00290 { WSA_QOS_RECEIVERS, "At least one reserve has arrived." }, 00291 { WSA_QOS_SENDERS, "At least one path has arrived." }, 00292 { WSA_QOS_NO_SENDERS, "There are no senders." }, 00293 { WSA_QOS_NO_RECEIVERS, "There are no receivers." }, 00294 { WSA_QOS_REQUEST_CONFIRMED, "Reserve has been confirmed." }, 00295 { WSA_QOS_ADMISSION_FAILURE, "Error due to lack of resources." }, 00296 { WSA_QOS_POLICY_FAILURE, "Rejected for administrative reasons - bad credentials." }, 00297 { WSA_QOS_BAD_STYLE, "Unknown or conflicting style." }, 00298 { WSA_QOS_BAD_OBJECT, "Problem with some part of the filterspec or providerspecific buffer in general." }, 00299 { WSA_QOS_TRAFFIC_CTRL_ERROR, "Problem with some part of the flowspec." }, 00300 { WSA_QOS_GENERIC_ERROR, "General QOS error." }, 00301 { WSA_QOS_ESERVICETYPE, "An invalid or unrecognized service type was found in the flowspec." }, 00302 { WSA_QOS_EFLOWSPEC, "An invalid or inconsistent flowspec was found in the QOS structure." }, 00303 { WSA_QOS_EPROVSPECBUF, "Invalid QOS provider-specific buffer." }, 00304 { WSA_QOS_EFILTERSTYLE, "An invalid QOS filter style was used." }, 00305 { WSA_QOS_EFILTERTYPE, "An invalid QOS filter type was used." }, 00306 { WSA_QOS_EFILTERCOUNT, "An incorrect number of QOS FILTERSPECs were specified in the FLOWDESCRIPTOR." }, 00307 { WSA_QOS_EOBJLENGTH, "An object with an invalid ObjectLength field was specified in the QOS provider-specific buffer." }, 00308 { WSA_QOS_EFLOWCOUNT, "An incorrect number of flow descriptors was specified in the QOS structure." }, 00309 { WSA_QOS_EUNKOWNPSOBJ, "An unrecognized object was found in the QOS provider-specific buffer." }, 00310 { WSA_QOS_EPOLICYOBJ, "An invalid policy object was found in the QOS provider-specific buffer." }, 00311 { WSA_QOS_EFLOWDESC, "An invalid QOS flow descriptor was found in the flow descriptor list." }, 00312 { WSA_QOS_EPSFLOWSPEC, "An invalid or inconsistent flowspec was found in the QOS provider specific buffer." }, 00313 { WSA_QOS_EPSFILTERSPEC, "An invalid FILTERSPEC was found in the QOS provider-specific buffer." }, 00314 { WSA_QOS_ESDMODEOBJ, "An invalid shape discard mode object was found in the QOS provider specific buffer." }, 00315 { WSA_QOS_ESHAPERATEOBJ, "An invalid shaping rate object was found in the QOS provider-specific buffer." }, 00316 { WSA_QOS_RESERVED_PETYPE, "A reserved policy element was found in the QOS provider-specific buffer." }, 00317 } ; 00318 00319 // Find the entry with matching error code 00320 for (int i=0; i<sizeof(errorTexts)/sizeof(errorTexts[0]); i++) 00321 { 00322 if (errorTexts[i].errorCode==errorCode) 00323 { 00324 // Return the corresponding error message 00325 return errorTexts[i].errorMessage; 00326 } 00327 } 00328 00329 // If an unknown error code was passed in, return a default message 00330 return "Unknown error!"; 00331 };
Reproduction/republishing of any material on this site without permission is strictly prohibited.
