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 socklen_t 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 Address = sfIPAddress(inet_ntoa(Sender.sin_addr));
00152 SizeReceived = static_cast<std::size_t>(Received);
00153 }
00154 else
00155 {
00156 Address = sfIPAddress();
00157 return false;
00158 }
00159 }
00160 else
00161 {
00162
00163 std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
00164 return false;
00165 }
00166
00167 return true;
00168 }
00169
00170
00174 bool sfSocketUDP::Send(sfPacket& Packet, const sfIPAddress& Address, unsigned short Port)
00175 {
00176
00177 Packet.OnSend();
00178
00179
00180 sfUint32 PacketSize = htonl(Packet.GetDataSize());
00181 if (!Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize), Address, Port))
00182 return false;
00183
00184
00185 if (!Send(Packet.GetData(), Packet.GetDataSize(), Address, Port))
00186 return false;
00187
00188 return true;
00189 }
00190
00191
00197 bool sfSocketUDP::Receive(sfPacket& Packet, sfIPAddress& Address, unsigned short Port)
00198 {
00199
00200
00201
00202
00203
00204 std::size_t Received = 0;
00205 sfUint32 PacketSize = 0;
00206 Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received, Address, Port);
00207 PacketSize = ntohl(PacketSize);
00208
00209
00210 Packet.Clear();
00211
00212
00213
00214 sfIPAddress Sender;
00215
00216
00217 char Buffer[1024];
00218 while (Packet.GetDataSize() < PacketSize)
00219 {
00220
00221 if (!Receive(Buffer, sizeof(Buffer), Received, Sender, Port))
00222 return false;
00223
00224
00225 if (Sender == Address)
00226 Packet.Append(Buffer, Received);
00227 }
00228
00229
00230 Packet.OnReceive();
00231
00232 return true;
00233 }
00234
00235
00239 bool sfSocketUDP::Close()
00240 {
00241 if (sf_private::close(mySocket) == -1)
00242 {
00243 std::cerr << "Failed to close socket" << std::endl;
00244 return false;
00245 }
00246
00247 return true;
00248 }
00249
00250
00254 bool sfSocketUDP::operator ==(const sfSocketUDP& Other) const
00255 {
00256 return mySocket == Other.mySocket;
00257 }
00258
00259
00263 bool sfSocketUDP::operator !=(const sfSocketUDP& Other) const
00264 {
00265 return mySocket != Other.mySocket;
00266 }
00267
00268
00274 bool sfSocketUDP::operator <(const sfSocketUDP& Other) const
00275 {
00276 return mySocket < Other.mySocket;
00277 }
00278
00279
00284 sfSocketUDP::sfSocketUDP(sf_private::sfSocketType Descriptor) :
00285 mySocket(Descriptor),
00286 myPort (0)
00287 {
00288
00289 }
00290
00291
00295 void sfSocketUDP::Create()
00296 {
00297
00298 mySocket = socket(PF_INET, SOCK_DGRAM, 0);
00299
00300
00301 myPort = 0;
00302
00303
00304 char Yes = 1;
00305 if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, &Yes, sizeof(int)) == -1)
00306 {
00307 std::cerr << "Failed to set socket option \"reuse address\" ; "
00308 << "binding to a same port may fail if too fast" << std::endl;
00309 }
00310
00311
00312 if (setsockopt(mySocket, SOL_SOCKET, SO_BROADCAST, &Yes, sizeof(int)) == -1)
00313 {
00314 std::cerr << "Failed to enable broadcast on UDP socket" << std::endl;
00315 }
00316 }