00001 00002 // 00003 // SFML - Simple and Fast Multimedia Library 00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) 00005 // 00006 // This software is provided 'as-is', without any express or implied warranty. 00007 // In no event will the authors be held liable for any damages arising from the use of this software. 00008 // 00009 // Permission is granted to anyone to use this software for any purpose, 00010 // including commercial applications, and to alter it and redistribute it freely, 00011 // subject to the following restrictions: 00012 // 00013 // 1. The origin of this software must not be misrepresented; 00014 // you must not claim that you wrote the original software. 00015 // If you use this software in a product, an acknowledgment 00016 // in the product documentation would be appreciated but is not required. 00017 // 00018 // 2. Altered source versions must be plainly marked as such, 00019 // and must not be misrepresented as being the original software. 00020 // 00021 // 3. This notice may not be removed or altered from any source distribution. 00022 // 00024 00026 // Headers 00028 #include <SFML/Network/IPAddress.hpp> 00029 #include <SFML/Network/Http.hpp> 00030 #include <SFML/Network/SocketHelper.hpp> 00031 #include <string.h> 00032 00033 00034 namespace sf 00035 { 00039 const IPAddress IPAddress::LocalHost("127.0.0.1"); 00040 00041 00045 IPAddress::IPAddress() : 00046 myAddress(INADDR_NONE) 00047 { 00048 00049 } 00050 00051 00055 IPAddress::IPAddress(const std::string& address) 00056 { 00057 // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx") 00058 myAddress = inet_addr(address.c_str()); 00059 00060 // If not successful, try to convert it as a host name 00061 if (!IsValid()) 00062 { 00063 hostent* host = gethostbyname(address.c_str()); 00064 if (host) 00065 { 00066 // Host found, extract its IP address 00067 myAddress = reinterpret_cast<in_addr*>(host->h_addr)->s_addr; 00068 } 00069 else 00070 { 00071 // Host name not found on the network 00072 myAddress = INADDR_NONE; 00073 } 00074 } 00075 } 00076 00077 00082 IPAddress::IPAddress(const char* address) 00083 { 00084 // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx") 00085 myAddress = inet_addr(address); 00086 00087 // If not successful, try to convert it as a host name 00088 if (!IsValid()) 00089 { 00090 hostent* host = gethostbyname(address); 00091 if (host) 00092 { 00093 // Host found, extract its IP address 00094 myAddress = reinterpret_cast<in_addr*>(host->h_addr)->s_addr; 00095 } 00096 else 00097 { 00098 // Host name not found on the network 00099 myAddress = INADDR_NONE; 00100 } 00101 } 00102 } 00103 00104 00108 IPAddress::IPAddress(Uint8 byte0, Uint8 byte1, Uint8 byte2, Uint8 byte3) 00109 { 00110 myAddress = htonl((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 00111 } 00112 00113 00117 IPAddress::IPAddress(Uint32 address) 00118 { 00119 myAddress = htonl(address); 00120 } 00121 00122 00126 bool IPAddress::IsValid() const 00127 { 00128 return myAddress != INADDR_NONE; 00129 } 00130 00131 00135 std::string IPAddress::ToString() const 00136 { 00137 in_addr address; 00138 address.s_addr = myAddress; 00139 00140 return inet_ntoa(address); 00141 } 00142 00143 00147 Uint32 IPAddress::ToInteger() const 00148 { 00149 return ntohl(myAddress); 00150 } 00151 00152 00156 IPAddress IPAddress::GetLocalAddress() 00157 { 00158 // The method here is to connect a UDP socket to anyone (here to localhost), 00159 // and get the local socket address with the getsockname function. 00160 // UDP connection will not send anything to the network, so this function won't cause any overhead. 00161 00162 IPAddress localAddress; 00163 00164 // Create the socket 00165 SocketHelper::SocketType sock = socket(PF_INET, SOCK_DGRAM, 0); 00166 if (sock == SocketHelper::InvalidSocket()) 00167 return localAddress; 00168 00169 // Build the host address (use a random port) 00170 sockaddr_in sockAddr; 00171 memset(sockAddr.sin_zero, 0, sizeof(sockAddr.sin_zero)); 00172 sockAddr.sin_addr.s_addr = INADDR_LOOPBACK; 00173 sockAddr.sin_family = AF_INET; 00174 sockAddr.sin_port = htons(4567); 00175 00176 // Connect the socket 00177 if (connect(sock, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr)) == -1) 00178 { 00179 SocketHelper::Close(sock); 00180 return localAddress; 00181 } 00182 00183 // Get the local address of the socket connection 00184 SocketHelper::LengthType size = sizeof(sockAddr); 00185 if (getsockname(sock, reinterpret_cast<sockaddr*>(&sockAddr), &size) == -1) 00186 { 00187 SocketHelper::Close(sock); 00188 return localAddress; 00189 } 00190 00191 // Close the socket 00192 SocketHelper::Close(sock); 00193 00194 // Finally build the IP address 00195 localAddress.myAddress = sockAddr.sin_addr.s_addr; 00196 00197 return localAddress; 00198 } 00199 00200 00204 IPAddress IPAddress::GetPublicAddress(float timeout) 00205 { 00206 // The trick here is more complicated, because the only way 00207 // to get our public IP address is to get it from a distant computer. 00208 // Here we get the web page from http://www.sfml-dev.org/ip-provider.php 00209 // and parse the result to extract our IP address 00210 // (not very hard : the web page contains only our IP address). 00211 00212 Http server("www.sfml-dev.org"); 00213 Http::Request request(Http::Request::Get, "/ip-provider.php"); 00214 Http::Response page = server.SendRequest(request, timeout); 00215 if (page.GetStatus() == Http::Response::Ok) 00216 return IPAddress(page.GetBody()); 00217 00218 // Something failed: return an invalid address 00219 return IPAddress(); 00220 } 00221 00222 00226 bool IPAddress::operator ==(const IPAddress& other) const 00227 { 00228 return myAddress == other.myAddress; 00229 } 00230 00231 00235 bool IPAddress::operator !=(const IPAddress& other) const 00236 { 00237 return myAddress != other.myAddress; 00238 } 00239 00240 00244 bool IPAddress::operator <(const IPAddress& other) const 00245 { 00246 return myAddress < other.myAddress; 00247 } 00248 00249 00253 bool IPAddress::operator >(const IPAddress& other) const 00254 { 00255 return myAddress > other.myAddress; 00256 } 00257 00258 00262 bool IPAddress::operator <=(const IPAddress& other) const 00263 { 00264 return myAddress <= other.myAddress; 00265 } 00266 00267 00271 bool IPAddress::operator >=(const IPAddress& other) const 00272 { 00273 return myAddress >= other.myAddress; 00274 } 00275 00276 00280 std::istream& operator >>(std::istream& stream, IPAddress& address) 00281 { 00282 std::string str; 00283 stream >> str; 00284 address = IPAddress(str); 00285 00286 return stream; 00287 } 00288 00289 00293 std::ostream& operator <<(std::ostream& stream, const IPAddress& address) 00294 { 00295 return stream << address.ToString(); 00296 } 00297 00298 } // namespace sf
:: Copyright © 2007-2008 Laurent Gomila, all rights reserved :: Documentation generated by doxygen 1.5.2 ::