Platform_Win32_Network_Server.cpp
Go to the documentation of this file.00001 //*** Platform_Win32_Network_Server.cpp *** 00002 00003 #define WIN32_LEAN_AND_MEAN 00004 #define VC_EXTRALEAN 00005 #include <winsock2.h> 00006 00007 #pragma warning (push) 00008 #pragma warning( disable: 4127) 00009 #pragma warning( disable: 4706) 00010 #include <ws2tcpip.h> 00011 #pragma warning (pop) 00012 00013 #include "Platform_Win32_Network_Server.h" 00014 00015 #include "Platform_Win32_Network.h" 00016 #include "Debug.h" 00017 #include "StandardLibrary.h" 00018 00019 00020 //*** Constructor (listening) *** 00021 00022 Platform_Win32_Network_Server::Platform_Win32_Network_Server(Platform_Win32_Network* network, Platform_Network::ConnectionMode mode, int port): 00023 network_(network), 00024 isListening_(false), 00025 isConnected_(false), 00026 mode_(mode), 00027 port_(port), 00028 socket_(0) 00029 { 00030 /* 00031 -1. Initialize Winsock. 00032 -2. Create a socket. 00033 -3. Bind the socket. 00034 4. Listen on the socket for a client. 00035 5. Accept a connection from a client. 00036 6. Receive and send data. 00037 7. Disconnect. 00038 */ 00039 00040 00041 // Set up hints for getaddrinfo 00042 addrinfo hints; 00043 MemSet(&hints,0,sizeof(hints)); 00044 hints.ai_family = AF_INET; // The Internet Protocol version 4 (IPv4) address family. 00045 hints.ai_flags = AI_PASSIVE; 00046 00047 if (mode_==Platform_Network::ConnectionMode_TCP) 00048 { 00049 hints.ai_socktype = SOCK_STREAM; // Socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. 00050 hints.ai_protocol = IPPROTO_TCP; // Use Transmission Control Protocol (TCP). 00051 } 00052 else if (mode_==Platform_Network::ConnectionMode_UDP) 00053 { 00054 hints.ai_socktype = SOCK_DGRAM; // Socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. 00055 hints.ai_protocol = IPPROTO_UDP; // Use User Datagram Protocol (UDP). 00056 } 00057 00058 // Resolve the local address and port to be used by the server 00059 addrinfo* result = 0; 00060 char portString[256]; 00061 SNPrintF(portString,256,"%d",port_); // We need the port as a string 00062 if (getaddrinfo(0, portString, &hints, &result)!=0) 00063 { 00064 DebugPrint(("getaddrinfo - FAILED\n")); 00065 network_->DisableNetworking(); 00066 return; 00067 } 00068 00069 00070 // Create the socket 00071 socket_ = socket(result->ai_family, result->ai_socktype, result->ai_protocol); 00072 if (socket_==INVALID_SOCKET) 00073 { 00074 freeaddrinfo(result); 00075 DebugPrint(("FAILED creating socket!\n")); 00076 network_->DisableNetworking(); 00077 return; 00078 } 00079 00080 00081 // Bind the socket to our local server address 00082 if (bind(socket_, result->ai_addr, (int)result->ai_addrlen)==SOCKET_ERROR) 00083 { 00084 freeaddrinfo(result); 00085 closesocket(socket_); 00086 socket_=INVALID_SOCKET; 00087 DebugPrint(("FAILED binding socket!\n")); 00088 network_->DisableNetworking(); 00089 return; 00090 } 00091 00092 // Make the socket listen 00093 if (listen(socket_, SOMAXCONN)==SOCKET_ERROR) // Set the maximum number of connections to lots 00094 { 00095 freeaddrinfo(result); 00096 closesocket(socket_); 00097 socket_=INVALID_SOCKET; 00098 DebugPrint(("listen FAILED!\n")); 00099 network_->DisableNetworking(); 00100 return; 00101 } 00102 00103 freeaddrinfo(result); 00104 } 00105 00106 00107 //*** Constructor *** 00108 /* 00109 Platform_Win32_Network_Server::Platform_Win32_Network_Server(Platform_Network::ConnectionMode mode, const char* address, int port): 00110 isListening_(false), 00111 mode_(mode), 00112 port_(port), 00113 address_(0), 00114 socket_(0) 00115 { 00116 address_=StrDup(address); 00117 00118 // 00119 //1. Initialize Winsock. 00120 //2. Create a socket. 00121 //3. Connect to the server. 00122 //4. Send and receive data. 00123 //5. Disconnect. 00125 00126 // Store information about the server 00127 LPHOSTENT hostEntry; 00128 00129 hostEntry = gethostbyname(address_); // Specifying the server by its name; 00130 // another option is gethostbyaddr() (see below) 00131 00132 if (!hostEntry) { 00133 int nret = WSAGetLastError(); 00134 nret; // Avoid warning: unreferenced formal parameter 00135 00136 } 00137 // USE THIS INSTEAD!! The other one is deprecated 00138 // LPHOSTENT hostEntry; 00139 // in_addr iaHost; 00140 // 00141 // iaHost.s_addr = inet_addr("204.52.135.52"); 00142 // 00143 // hostEntry = gethostbyaddrstatic_cast<const char*>(&iaHost), sizeof(struct in_addr), AF_INET); 00144 // 00145 // if (!hostEntry) { 00146 // nret = WSAGetLastError(); 00147 // ReportError(nret, "gethostbyaddr()"); // Report the error as before 00148 // 00149 // WSACleanup(); 00150 // return NETWORK_ERROR; 00151 // } 00152 // 00153 00154 00155 // Create the socket 00156 if (mode_==Platform_Network::ConnectionMode_TCP) 00157 { 00158 socket_=socket( AF_INET, // The Internet Protocol version 4 (IPv4) address family. 00159 SOCK_STREAM, // Socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. 00160 IPPROTO_TCP); // Use Transmission Control Protocol (TCP). 00161 00162 } 00163 else 00164 { 00165 socket_=socket( AF_INET, // The Internet Protocol version 4 (IPv4) address family. 00166 SOCK_DGRAM, // Socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. 00167 IPPROTO_UDP); // Use TUser Datagram Protocol (UDP). 00168 00169 } 00170 00171 Assert(socket_!=INVALID_SOCKET,"Failed to create socket"); 00172 00173 00174 // Fill a SOCKADDR_IN struct with address information 00175 SOCKADDR_IN serverInfo; 00176 00177 serverInfo.sin_family = AF_INET; 00178 00179 // At this point, we've successfully retrieved vital information about the server, 00180 // including its hostname, aliases, and IP addresses. Wait; how could a single 00181 // computer have multiple addresses, and exactly what is the following line doing? 00182 // See the explanation below. 00183 00184 serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list); 00185 00186 serverInfo.sin_port = htons(80); // Change to network-byte order and 00187 // insert into port field 00188 00189 00190 // Connect to the server 00191 int nret = connect(socket_, 00192 (LPSOCKADDR)&serverInfo, 00193 sizeof(struct sockaddr)); 00194 00195 if (nret == SOCKET_ERROR) { 00196 nret = WSAGetLastError(); 00197 } 00198 00199 00200 // Successfully connected! 00201 00202 00203 // Send/receive, then cleanup: 00204 closesocket(socket_); 00205 WSACleanup(); 00206 } 00207 */ 00208 00209 00210 //*** Destructor *** 00211 00212 Platform_Win32_Network_Server::~Platform_Win32_Network_Server() 00213 { 00214 00215 if (socket_!=INVALID_SOCKET) 00216 { 00217 closesocket(socket_); 00218 socket_=INVALID_SOCKET; 00219 } 00220 } 00221 00222 00223 //*** IsListening *** 00224 00225 bool Platform_Win32_Network_Server::IsListening() 00226 { 00227 return isListening_; 00228 } 00229 00230 00231 //*** GetConnectionMode *** 00232 00233 Platform_Network::ConnectionMode Platform_Win32_Network_Server::GetConnectionMode() 00234 { 00235 return mode_; 00236 } 00237 00238 00239 //*** GetAddress *** 00240 /* 00241 const char* Platform_Win32_Network_Server::GetAddress() 00242 { 00243 return address_; 00244 } 00245 */ 00246 00247 //*** GetPort *** 00248 00249 int Platform_Win32_Network_Server::GetPort() 00250 { 00251 return port_; 00252 } 00253 00254 00255 //*** Connect *** 00256 /* 00257 bool Platform_Win32_Network_Server::Connect() 00258 { 00259 return false; 00260 } 00261 */ 00262 00263 //*** Disconnect *** 00264 00265 bool Platform_Win32_Network_Server::Disconnect() 00266 { 00267 return false; 00268 } 00269 00270 00271 //*** IsConnected *** 00272 00273 bool Platform_Win32_Network_Server::IsConnected() 00274 { 00275 return false; 00276 } 00277 00278 00279 //*** SendData *** 00280 00281 int Platform_Win32_Network_Server::SendData(void* buffer, int size) 00282 { 00283 // char buffer[256]; // Declaring a buffer on the stack 00284 // char *buffer = new char[256]; // or on the heap 00285 00286 ZeroMemory(buffer, 256); 00287 // strcpy(buffer, "Pretend this is important data."); 00288 00289 int nret = send(socket_, 00290 static_cast<char*>(buffer), 00291 size, // Note that this specifies the length of the string; not 00292 // the size of the entire buffer 00293 0); // Most often is zero, but see MSDN for other options 00294 00295 delete [] buffer; // If and only if the heap declaration was used 00296 00297 if (nret == SOCKET_ERROR) { 00298 // Get a specific code 00299 // Handle accordingly 00300 return 0; 00301 } else { 00302 // nret contains the number of bytes sent 00303 } 00304 00305 return 0; 00306 } 00307 00308 00309 //*** GetReceivedData *** 00310 00311 int Platform_Win32_Network_Server::GetReceivedSize() 00312 { 00313 return 0; 00314 } 00315 00316 00317 //*** GetReceivedData *** 00318 00319 int Platform_Win32_Network_Server::GetReceivedData(void* buffer, int size) 00320 { 00321 int nret = recv(socket_, 00322 static_cast<char*>(buffer), 00323 size, // Complete size of buffer 00324 0); 00325 00326 delete [] buffer; // Manipulate buffer, then delete if and only if 00327 // buffer was allocated on heap 00328 00329 if (nret == SOCKET_ERROR) { 00330 // Get a specific code 00331 // Handle accordingly 00332 return 0; 00333 } else { 00334 // nret contains the number of bytes received 00335 } 00336 00337 00338 return 0; 00339 } 00340 00341 00342 //*** Update *** 00343 00344 void Platform_Win32_Network_Server::Update() 00345 { 00346 /* if (isListening_) 00347 { 00348 // Wait for a client 00349 SOCKET theClient; 00350 00351 theClient = accept(socket_, 00352 NULL, // Address of a sockaddr structure (see explanation below) 00353 NULL); // Address of a variable containing size of sockaddr struct 00354 00355 if (theClient == INVALID_SOCKET) { 00356 nret = WSAGetLastError(); 00357 } 00358 00359 00360 // Send and receive from the client, and finally, 00361 closesocket(theClient); 00362 closesocket(socket_); 00363 } 00364 00365 */ } 00366 00367 00368 bool Platform_Win32_Network_Server::Listen() 00369 { 00370 return true; 00371 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
