D:/Programmation/Cpp/SFML/src/SFML/Network/IPAddress.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 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/Sockets.hpp>
00030 
00031 
00035 const sfIPAddress sfIPAddress::Broadcast("255.255.255.255");
00036 const sfIPAddress sfIPAddress::LocalHost("127.0.0.1");
00037 
00038 
00042 sfIPAddress::sfIPAddress() :
00043 myAddress(htonl(INADDR_ANY))
00044 {
00045 
00046 }
00047 
00048 
00052 sfIPAddress::sfIPAddress(const std::string& Address)
00053 {
00054     // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
00055     myAddress = inet_addr(Address.c_str());
00056 
00057     // If not successful, try to convert it as a host name
00058     if (!IsValid())
00059     {
00060         hostent* Host = gethostbyname(Address.c_str());
00061         if (Host)
00062         {
00063             // Host found, extract its IP address
00064             myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
00065         }
00066         else
00067         {
00068             // Host name not found on the network
00069             myAddress = INADDR_NONE;
00070         }
00071     }
00072 }
00073 
00074 
00078 sfIPAddress::sfIPAddress(sfUint8 Byte0, sfUint8 Byte1, sfUint8 Byte2, sfUint8 Byte3)
00079 {
00080     myAddress = htonl((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);
00081 }
00082 
00083 
00087 bool sfIPAddress::IsValid() const
00088 {
00089     return myAddress != INADDR_NONE;
00090 }
00091 
00092 
00096 std::string sfIPAddress::ToString() const
00097 {
00098     in_addr InAddr;
00099     InAddr.s_addr = myAddress;
00100 
00101     return inet_ntoa(InAddr);
00102 }
00103 
00104 
00108 sfIPAddress sfIPAddress::GetLocalAddress()
00109 {
00110     // The method here is to connect a UDP socket to anyone (here to localhost),
00111     // and get the local socket address with the getsockname function.
00112     // UDP connection will not send anything to the network, so this function won't cause any overhead
00113 
00114     sfIPAddress LocalAddress;
00115 
00116     // Create the socket
00117     sf_private::sfSocketType Socket = socket(PF_INET, SOCK_DGRAM, 0);
00118     if (Socket == INVALID_SOCKET)
00119         return LocalAddress;
00120 
00121     // Build the host address (use a random port)
00122     sockaddr_in SockAddr;
00123     memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
00124     SockAddr.sin_addr.s_addr = INADDR_LOOPBACK;
00125     SockAddr.sin_family      = AF_INET;
00126     SockAddr.sin_port        = htons(4567);
00127 
00128     // Connect the socket
00129     if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
00130     {
00131         sf_private::close(Socket);
00132         return LocalAddress;
00133     }
00134  
00135     // Get the local address of the socket connection
00136     int Size = sizeof(SockAddr);
00137     if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1)
00138     {
00139         sf_private::close(Socket);
00140         return LocalAddress;
00141     }
00142 
00143     // Close the socket
00144     sf_private::close(Socket);
00145 
00146     // Finally build the IP address
00147     LocalAddress.myAddress = SockAddr.sin_addr.s_addr;
00148 
00149     return LocalAddress;
00150 }
00151 
00152 
00156 sfIPAddress sfIPAddress::GetPublicAddress()
00157 {
00158     // The trick here is more complicated, because the only way
00159     // to get our public IP address is to get it from a distant computer.
00160     // Here we get the web page from http://www.whatismyip.org
00161     // and parse the result to extract our IP address
00162     // (not very hard : the web page contains only our IP address)
00163 
00164     sfIPAddress PublicAddress;
00165 
00166     // Create the socket
00167     sf_private::sfSocketType Socket = socket(PF_INET, SOCK_STREAM, 0);
00168     if (Socket == INVALID_SOCKET)
00169         return PublicAddress;
00170 
00171     // Build the server address (use port 80 for HTTP)
00172     sfIPAddress Server("www.whatismyip.org");
00173     sockaddr_in SockAddr;
00174     memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
00175     SockAddr.sin_addr.s_addr = inet_addr(Server.ToString().c_str());
00176     SockAddr.sin_family      = AF_INET;
00177     SockAddr.sin_port        = htons(80);
00178 
00179     // Connect the socket
00180     if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
00181     {
00182         sf_private::close(Socket);
00183         return PublicAddress;
00184     }
00185 
00186     // Send a request for getting the index page
00187     const char Request[] = "GET / HTTP/1.0\r\n"
00188                            "From: camembert@fromage.com\r\n"
00189                            "User-Agent: SFML/1.0\r\n"
00190                            "\r\n";
00191     if (send(Socket, Request, sizeof(Request), 0) <= 0)
00192     {
00193         sf_private::close(Socket);
00194         return PublicAddress;
00195     }
00196 
00197     // Get the response (the source code of the web page)
00198     char Response[1024];
00199     int Received = recv(Socket, Response, sizeof(Response), 0);
00200     if (Received <= 0)
00201     {
00202         sf_private::close(Socket);
00203         return PublicAddress;
00204     }
00205 
00206     // Close the socket
00207     sf_private::close(Socket);
00208 
00209     // Extract the address from the source code of the web page
00210     // (extract from first \r\n\r\n to the end)
00211     std::string Page(Response, Received);
00212     std::string::size_type Start = Page.find("\r\n\r\n");
00213     if (Start != std::string::npos)
00214     {
00215         PublicAddress = Page.substr(Start + 4);
00216     }
00217 
00218     return PublicAddress;
00219 }
00220 
00221 
00225 bool sfIPAddress::operator ==(const sfIPAddress& Other) const
00226 {
00227     return myAddress == Other.myAddress;
00228 }
00229 
00230 
00234 bool sfIPAddress::operator !=(const sfIPAddress& Other) const
00235 {
00236     return myAddress != Other.myAddress;
00237 }
00238 
00239 
00243 bool sfIPAddress::operator <(const sfIPAddress& Other) const
00244 {
00245     return myAddress < Other.myAddress;
00246 }
00247 
00248 
00252 bool sfIPAddress::operator >(const sfIPAddress& Other) const
00253 {
00254     return myAddress > Other.myAddress;
00255 }
00256 
00257 
00261 bool sfIPAddress::operator <=(const sfIPAddress& Other) const
00262 {
00263     return myAddress <= Other.myAddress;
00264 }
00265 
00266 
00270 bool sfIPAddress::operator >=(const sfIPAddress& Other) const
00271 {
00272     return myAddress >= Other.myAddress;
00273 }
00274 
00275 
00279 std::istream& operator >>(std::istream& Stream, sfIPAddress& Address)
00280 {
00281     std::string Str;
00282     Stream >> Str;
00283     Address = sfIPAddress(Str);
00284 
00285     return Stream;
00286 }
00287 
00288 
00292 std::ostream& operator <<(std::ostream& Stream, const sfIPAddress& Address)
00293 {
00294     return Stream << Address.ToString();
00295 }

Generated for SFML by  doxygen 1.5.2