00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00026
00028 #include <SFML/Network/SocketUDP.hpp>
00029 #include <SFML/Network/IPAddress.hpp>
00030 #include <SFML/Network/Packet.hpp>
00031 #include <iostream>
00032
00033
00034 namespace sf
00035 {
00039 SocketUDP::SocketUDP() :
00040 mySocket(0),
00041 myPort (0)
00042 {
00043 Create();
00044 }
00045
00046
00050 bool SocketUDP::Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port)
00051 {
00052
00053 if (mySocket == INVALID_SOCKET)
00054 return false;
00055
00056
00057 if (Data && Size)
00058 {
00059
00060 sockaddr_in Target;
00061 Target.sin_family = AF_INET;
00062 Target.sin_port = htons(Port);
00063 Target.sin_addr.s_addr = inet_addr(Address.ToString().c_str());
00064 memset(Target.sin_zero, 0, sizeof(Target.sin_zero));
00065
00066
00067 int Sent = 0;
00068 int SizeToSend = static_cast<int>(Size);
00069 for (int Length = 0; Length < SizeToSend; Length += Sent)
00070 {
00071
00072 Sent = sendto(mySocket, Data + Length, SizeToSend - Length, 0, reinterpret_cast<sockaddr*>(&Target), sizeof(Target));
00073
00074
00075 if (Sent <= 0)
00076 return false;
00077 }
00078 }
00079 else
00080 {
00081
00082 std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl;
00083 return false;
00084 }
00085
00086 return true;
00087 }
00088
00089
00095 bool SocketUDP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address, unsigned short Port)
00096 {
00097
00098 SizeReceived = 0;
00099
00100
00101 if (mySocket == INVALID_SOCKET)
00102 return false;
00103
00104
00105 if (Data && MaxSize)
00106 {
00107
00108 if (myPort != Port)
00109 {
00110
00111 if (myPort != 0)
00112 {
00113
00114 Close();
00115
00116
00117 Create();
00118 }
00119
00120
00121 sockaddr_in Addr;
00122 Addr.sin_family = AF_INET;
00123 Addr.sin_port = htons(Port);
00124 Addr.sin_addr.s_addr = INADDR_ANY;
00125 memset(Addr.sin_zero, 0, sizeof(Addr.sin_zero));
00126
00127
00128 if (bind(mySocket, reinterpret_cast<sockaddr*>(&Addr), sizeof(Addr)) == -1)
00129 {
00130 std::cerr << "Failed to bind the socket to port " << Port << std::endl;
00131 myPort = 0;
00132 return false;
00133 }
00134
00135
00136 myPort = Port;
00137 }
00138
00139
00140 sockaddr_in Sender;
00141 Sender.sin_family = AF_INET;
00142 Sender.sin_port = htons(myPort);
00143 Sender.sin_addr.s_addr = INADDR_ANY;
00144 memset(Sender.sin_zero, 0, sizeof(Sender.sin_zero));
00145 socklen_t SenderSize = sizeof(Sender);
00146
00147
00148 int Received = recvfrom(mySocket, Data, static_cast<int>(MaxSize), 0, reinterpret_cast<sockaddr*>(&Sender), &SenderSize);
00149
00150
00151 if (Received > 0)
00152 {
00153 Address = IPAddress(inet_ntoa(Sender.sin_addr));
00154 SizeReceived = static_cast<std::size_t>(Received);
00155 }
00156 else
00157 {
00158 Address = IPAddress();
00159 return false;
00160 }
00161 }
00162 else
00163 {
00164
00165 std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
00166 return false;
00167 }
00168
00169 return true;
00170 }
00171
00172
00176 bool SocketUDP::Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port)
00177 {
00178
00179 PacketToSend.OnSend();
00180
00181
00182 Uint32 PacketSize = htonl(PacketToSend.GetDataSize());
00183 if (!Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize), Address, Port))
00184 return false;
00185
00186
00187 if (!Send(PacketToSend.GetData(), PacketToSend.GetDataSize(), Address, Port))
00188 return false;
00189
00190 return true;
00191 }
00192
00193
00199 bool SocketUDP::Receive(Packet& PacketToReceive, IPAddress& Address, unsigned short Port)
00200 {
00201
00202
00203
00204
00205
00206 std::size_t Received = 0;
00207 Uint32 PacketSize = 0;
00208 Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received, Address, Port);
00209 PacketSize = ntohl(PacketSize);
00210
00211
00212 PacketToReceive.Clear();
00213
00214
00215
00216 IPAddress Sender;
00217
00218
00219 char Buffer[1024];
00220 while (PacketToReceive.GetDataSize() < PacketSize)
00221 {
00222
00223 if (!Receive(Buffer, sizeof(Buffer), Received, Sender, Port))
00224 return false;
00225
00226
00227 if (Sender == Address)
00228 PacketToReceive.Append(Buffer, Received);
00229 }
00230
00231
00232 PacketToReceive.OnReceive();
00233
00234 return true;
00235 }
00236
00237
00241 bool SocketUDP::Close()
00242 {
00243 if (priv::close(mySocket) == -1)
00244 {
00245 std::cerr << "Failed to close socket" << std::endl;
00246 return false;
00247 }
00248
00249 return true;
00250 }
00251
00252
00256 bool SocketUDP::operator ==(const SocketUDP& Other) const
00257 {
00258 return mySocket == Other.mySocket;
00259 }
00260
00261
00265 bool SocketUDP::operator !=(const SocketUDP& Other) const
00266 {
00267 return mySocket != Other.mySocket;
00268 }
00269
00270
00276 bool SocketUDP::operator <(const SocketUDP& Other) const
00277 {
00278 return mySocket < Other.mySocket;
00279 }
00280
00281
00286 SocketUDP::SocketUDP(priv::SocketType Descriptor) :
00287 mySocket(Descriptor),
00288 myPort (0)
00289 {
00290
00291 }
00292
00293
00297 void SocketUDP::Create()
00298 {
00299
00300 mySocket = socket(PF_INET, SOCK_DGRAM, 0);
00301
00302
00303 myPort = 0;
00304
00305
00306 char Yes = 1;
00307 if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, &Yes, sizeof(int)) == -1)
00308 {
00309 std::cerr << "Failed to set socket option \"reuse address\" ; "
00310 << "binding to a same port may fail if too fast" << std::endl;
00311 }
00312
00313
00314 if (setsockopt(mySocket, SOL_SOCKET, SO_BROADCAST, &Yes, sizeof(int)) == -1)
00315 {
00316 std::cerr << "Failed to enable broadcast on UDP socket" << std::endl;
00317 }
00318 }
00319
00320 }