IPAddress.cpp
00001 00002 // 00003 // SFML - Simple and Fast Multimedia Library 00004 // Copyright (C) 2007-2009 Laurent Gomila ([email protected]) 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 InAddr; 00138 InAddr.s_addr = myAddress; 00139 00140 return inet_ntoa(InAddr); 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 Socket = socket(PF_INET, SOCK_DGRAM, 0); 00166 if (Socket == 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(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1) 00178 { 00179 SocketHelper::Close(Socket); 00180 return LocalAddress; 00181 } 00182 00183 // Get the local address of the socket connection 00184 SocketHelper::LengthType Size = sizeof(SockAddr); 00185 if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1) 00186 { 00187 SocketHelper::Close(Socket); 00188 return LocalAddress; 00189 } 00190 00191 // Close the socket 00192 SocketHelper::Close(Socket); 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 ::