D:/Programmation/Cpp/SFML/src/SFML/Network/SocketTCP.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/SocketTCP.hpp>
00029 #include <SFML/Network/IPAddress.hpp>
00030 #include <SFML/Network/Packet.hpp>
00031 #include <iostream>
00032 
00033 
00037 sfSocketTCP::sfSocketTCP() :
00038 mySocket(socket(PF_INET, SOCK_STREAM, 0))
00039 {
00040     // To avoid the "Address already in use" error message when trying to bind to the same port
00041     char Yes = 1;
00042     if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, &Yes, sizeof(int)) == -1)
00043     {
00044         std::cerr << "Failed to set socket option \"reuse address\" ; "
00045                   << "binding to a same port may fail if too fast" << std::endl;
00046     }
00047 }
00048 
00049 
00053 bool sfSocketTCP::Connect(unsigned short Port, const sfIPAddress& HostAddress)
00054 {
00055     // First check that socket is valid
00056     if (mySocket == INVALID_SOCKET)
00057         return false;
00058 
00059     // Build the host address
00060     sockaddr_in SockAddr;
00061     memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
00062     SockAddr.sin_addr.s_addr = inet_addr(HostAddress.ToString().c_str());
00063     SockAddr.sin_family      = AF_INET;
00064     SockAddr.sin_port        = htons(Port);
00065 
00066     // Connect
00067     if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
00068     {
00069         // :(
00070         std::cerr << "Failed to connect socket to host " << HostAddress << std::endl;
00071         return false;
00072     }
00073 
00074     return true;
00075 }
00076 
00077 
00081 bool sfSocketTCP::Listen(unsigned short Port)
00082 {
00083     // First check that socket is valid
00084     if (mySocket == INVALID_SOCKET)
00085         return false;
00086 
00087     // Build the address
00088     sockaddr_in SockAddr;
00089     memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
00090     SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00091     SockAddr.sin_family      = AF_INET;
00092     SockAddr.sin_port        = htons(Port);
00093 
00094     // Bind the socket to the specified port
00095     if (bind(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
00096     {
00097         // Not likely to happen, but...
00098         std::cerr << "Failed to bind socket to port " << Port << std::endl;
00099         return false;
00100     }
00101 
00102     // Listen to the bound port
00103     if (listen(mySocket, 0) == -1)
00104     {
00105         // Oops, socket is deaf
00106         std::cerr << "Failed to listen to port " << Port << std::endl;
00107         return false;
00108     }
00109 
00110     return true;
00111 }
00112 
00113 
00117 sfSocketTCP sfSocketTCP::Accept(sfIPAddress* Address)
00118 {
00119     // Address that will be filled with client informations
00120     sockaddr_in ClientAddress;
00121     int Length = sizeof(ClientAddress);
00122     sfSocketTCP ClientSocket = accept(mySocket, reinterpret_cast<sockaddr*>(&ClientAddress), &Length);
00123 
00124     // Fill address if requested
00125     if (Address)
00126         *Address = sfIPAddress(inet_ntoa(ClientAddress.sin_addr));
00127 
00128     return ClientSocket;
00129 }
00130 
00131 
00135 bool sfSocketTCP::Send(const char* Data, std::size_t Size)
00136 {
00137     // First check that socket is valid
00138     if (mySocket == INVALID_SOCKET)
00139         return false;
00140 
00141     // Check parameters
00142     if (Data && Size)
00143     {
00144         // Loop until every byte has been sent
00145         int Sent = 0;
00146         int SizeToSend = static_cast<int>(Size);
00147         for (int Length = 0; Length < SizeToSend; Length += Sent)
00148         {
00149             // Send a chunk of data
00150             Sent = send(mySocket, Data + Length, SizeToSend - Length, 0);
00151 
00152             // Check if connection is still alive
00153             if (Sent <= 0)
00154                 return false;
00155         }
00156     }
00157     else
00158     {
00159         // Error... (don't return false, we're still connected !)
00160         std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl;
00161     }
00162 
00163     return true;
00164 }
00165 
00166 
00172 bool sfSocketTCP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived)
00173 {
00174     // First clear the size received
00175     SizeReceived = 0;
00176 
00177     // Check that socket is valid
00178     if (mySocket == INVALID_SOCKET)
00179         return false;
00180 
00181     // Check parameters
00182     if (Data && MaxSize)
00183     {
00184         // Receive a chunk of bytes
00185         int Received = recv(mySocket, Data, static_cast<int>(MaxSize), 0);
00186 
00187         // Check the number of bytes received
00188         if (Received > 0)
00189             SizeReceived = static_cast<std::size_t>(Received);
00190         else
00191             return false;
00192     }
00193     else
00194     {
00195         // Error... (don't return false, we're still connected !)
00196         std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
00197     }
00198 
00199     return true;
00200 }
00201 
00202 
00206 bool sfSocketTCP::Send(sfPacket& Packet)
00207 {
00208     // Let the packet do custom stuff before sending it
00209     Packet.OnSend();
00210 
00211     // First send the packet size
00212     sfUint32 PacketSize = htonl(Packet.GetDataSize());
00213     if (!Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize)))
00214         return false;
00215 
00216     // Send the packet data
00217     if (!Send(Packet.GetData(), Packet.GetDataSize()))
00218         return false;
00219 
00220     return true;
00221 }
00222 
00223 
00229 bool sfSocketTCP::Receive(sfPacket& Packet)
00230 {
00231     // We start by getting the size of the incoming packet
00232     std::size_t Received   = 0;
00233     sfUint32    PacketSize = 0;
00234     if (!Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received))
00235         return false;
00236     PacketSize = ntohl(PacketSize);
00237 
00238     // Clear the packet
00239     Packet.Clear();
00240 
00241     // Then loop until we receive all the packet data
00242     char Buffer[1024];
00243     while (Packet.GetDataSize() < PacketSize)
00244     {
00245         // Receive a chunk of data
00246         if (!Receive(Buffer, sizeof(Buffer), Received))
00247             return false;
00248 
00249         // Append it into the packet
00250         Packet.Append(Buffer, Received);
00251     }
00252 
00253     // Let the packet do custom stuff after data reception
00254     Packet.OnReceive();
00255 
00256     return true;
00257 }
00258 
00259 
00263 bool sfSocketTCP::Close()
00264 {
00265     if (sf_private::close(mySocket) == -1)
00266     {
00267         std::cerr << "Failed to close socket" << std::endl;
00268         return false;
00269     }
00270 
00271     return true;
00272 }
00273 
00274 
00278 bool sfSocketTCP::operator ==(const sfSocketTCP& Other) const
00279 {
00280     return mySocket == Other.mySocket;
00281 }
00282 
00283 
00287 bool sfSocketTCP::operator !=(const sfSocketTCP& Other) const
00288 {
00289     return mySocket != Other.mySocket;
00290 }
00291 
00292 
00298 bool sfSocketTCP::operator <(const sfSocketTCP& Other) const
00299 {
00300     return mySocket < Other.mySocket;
00301 }
00302 
00303 
00308 sfSocketTCP::sfSocketTCP(sf_private::sfSocketType Descriptor) :
00309 mySocket(Descriptor)
00310 {
00311 
00312 }

Generated for SFML by  doxygen 1.5.2