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