00001 #include "net.h"
00002
00003 void NET::Init()
00004 {
00005 SDLNet_Init();
00006 }
00007
00008 NET::NET()
00009 {
00010 server = false;
00011 pin = pout = NULL;
00012 remote_socket = NULL;
00013 datacounter_rx = 0;
00014 datacounter_tx = 0;
00015 }
00016
00017 NET::~NET()
00018 {
00019 Disconnect();
00020 SDLNet_Quit();
00021 }
00022
00023 bool NET::Connect(string host, int port)
00024 {
00025 server = false;
00026 bool err = false;
00027
00028 if (host == "Server")
00029 server = true;
00030
00031 if (remote_socket != NULL)
00032 {
00033 SDLNet_UDP_Close(remote_socket);
00034 remote_socket = NULL;
00035 }
00036
00037 if (server)
00038 remote_socket = SDLNet_UDP_Open(port);
00039 else
00040 remote_socket = SDLNet_UDP_Open(0);
00041
00042 if (!server)
00043 {
00044 SDLNet_ResolveHost(&remote_ip, host.c_str(), port);
00045
00046 SDLNet_UDP_Unbind(remote_socket, 0);
00047 if (SDLNet_UDP_Bind(remote_socket, 0, &remote_ip)==-1)
00048 {
00049 err = true;
00050
00051 if (NET_DEBUG)
00052 {
00053 cout << "net: couldn't bind UDP socket to host " << host << " port " << port << endl;
00054 printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError());
00055 }
00056 }
00057 }
00058
00059
00060 if (pout == NULL)
00061 pout = SDLNet_AllocPacket(MAX_PACKET_SIZE);
00062 if (pin == NULL)
00063 pin = SDLNet_AllocPacket(MAX_PACKET_SIZE);
00064
00065 if (server)
00066 {
00067 }
00068 else
00069 {
00070 err = ClientHandshake();
00071 }
00072
00073 return !err;
00074 }
00075
00076 void NET::Update()
00077 {
00078 if (remote_socket == NULL)
00079 return;
00080
00081 int retval = SDLNet_UDP_Recv(remote_socket, pin);
00082
00083 if (retval >= 1 && connected)
00084 {
00085 BufferPacket(pin);
00086 }
00087
00088 if (retval >= 1 && !connected)
00089 {
00090 ServerHandshake();
00091 }
00092 }
00093
00094 bool NET::Connected()
00095 {
00096
00097
00098
00099
00100
00101 return connected;
00102 }
00103
00104 void NET::Disconnect()
00105 {
00106 if (remote_socket != NULL)
00107 {
00108 SDLNet_UDP_Close(remote_socket);
00109 remote_socket = NULL;
00110 connected = false;
00111 }
00112 }
00113
00114 bool NET::IsEqualToPacket(UDPpacket * p, Uint8 control, void * data, int size)
00115 {
00116 Uint8 * sourcedata = (Uint8 *) data;
00117
00118 if (p == NULL)
00119 {
00120 if (NET_DEBUG)
00121 {
00122 cout << "net: IsEqualToPacket: invalid packet" << endl;
00123 return false;
00124 }
00125 }
00126
00127 if (size + 2 >= p->maxlen)
00128 {
00129 if (NET_DEBUG)
00130 {
00131 cout << "net: IsEqualToPacket: packet size is too large: " << size << endl;
00132 return false;
00133 }
00134 }
00135
00136 if (p->len != size + 2)
00137 return false;
00138
00139 if (p->data[0] != replay.Get_FuncNetControl())
00140 return false;
00141
00142 if (p->data[1] != control)
00143 return false;
00144
00145 int i;
00146 for (i = 0; i < size; i++)
00147 {
00148 if (p->data[i+2] != sourcedata[i])
00149 return false;
00150 }
00151
00152 return true;
00153 }
00154
00155 void NET::WriteToPacket(UDPpacket * p, Uint8 control, void * data, int size)
00156 {
00157 Uint8 * sourcedata = (Uint8 *) data;
00158
00159 if (p == NULL)
00160 {
00161 if (NET_DEBUG)
00162 {
00163 cout << "net: WriteToPacket: invalid packet" << endl;
00164 return;
00165 }
00166 }
00167
00168 if (size + 2 >= p->maxlen)
00169 {
00170 if (NET_DEBUG)
00171 {
00172 cout << "net: WriteToPacket: packet size is too large: " << size << endl;
00173 return;
00174 }
00175 }
00176
00177 p->len = size + 2;
00178
00179 p->data[0] = replay.Get_FuncNetControl();
00180 p->data[1] = control;
00181
00182 int i;
00183 for (i = 0; i < size; i++)
00184 {
00185 p->data[i + 2] = sourcedata[i];
00186 }
00187 }
00188
00189 int NET::UDPSend(UDPpacket * p, int channel)
00190 {
00191 datacounter_tx += p->len;
00192
00193 if (!SDLNet_UDP_Send(remote_socket, channel, p))
00194 return UDP_FAILURE;
00195 else
00196 return UDP_SUCCESS;
00197 }
00198
00199 int NET::UDPRecv(UDPpacket * p, int channel, int timeout)
00200 {
00201 Uint32 t, t2;
00202
00203 t = SDL_GetTicks();
00204 t2 = SDL_GetTicks();
00205
00206 bool success = false;
00207
00208 while (!success && t2 - t < (Uint32) timeout)
00209 {
00210 int retval = SDLNet_UDP_Recv(remote_socket, p);
00211 if (retval >= 1)
00212 {
00213 success = true;
00214 }
00215
00216 t2=SDL_GetTicks();
00217 }
00218
00219 if (success)
00220 {
00221 datacounter_rx += p->len;
00222 return UDP_SUCCESS;
00223 }
00224
00225 if (t2 - t >= (Uint32) timeout)
00226 {
00227 return UDP_TIMEOUT;
00228 }
00229
00230 return UDP_FAILURE;
00231 }
00232
00233 bool NET::ClientHandshake()
00234 {
00235 string handshake = HANDSHAKESTR;
00236 string handshake_reply = HANDSHAKEREPLYSTR;
00237 int timeout = HANDSHAKETIMEOUT;
00238
00239 bool err = false;
00240
00241 WriteToPacket(pout, CONTROL_HANDSHAKE, (void *) handshake.c_str(), handshake.length());
00242 UDPSend(pout, 0);
00243 int ret = UDPRecv(pin, 0, timeout);
00244 if (ret == UDP_SUCCESS)
00245 {
00246 if (IsEqualToPacket(pin, CONTROL_HANDSHAKE, (void *) handshake_reply.c_str(), handshake_reply.length()))
00247 {
00248 connected = true;
00249 if (NET_DEBUG)
00250 cout << "net: Connection complete." << endl;
00251 }
00252 else
00253 {
00254 if (NET_DEBUG)
00255 cout << "net: Invalid handshake reply." << endl;
00256 err = true;
00257 }
00258 }
00259 if (ret == UDP_TIMEOUT)
00260 {
00261 err = true;
00262 if (NET_DEBUG)
00263 cout << "net: Handshake timeout, couldn't connect" << endl;
00264 }
00265 if (ret == UDP_FAILURE)
00266 {
00267 err = true;
00268 if (NET_DEBUG)
00269 cout << "net: Handshake error." << endl;
00270 }
00271
00272 return err;
00273 }
00274
00275
00276 bool NET::ServerHandshake()
00277 {
00278 string handshake = HANDSHAKESTR;
00279 string handshake_reply = HANDSHAKEREPLYSTR;
00280
00281
00282 bool err = false;
00283
00284 if (IsEqualToPacket(pin, CONTROL_HANDSHAKE, (void *) handshake.c_str(), handshake.length()))
00285 {
00286 SDLNet_UDP_Unbind(remote_socket, 0);
00287 if (SDLNet_UDP_Bind(remote_socket, 0, &(pin->address))==-1)
00288 {
00289 err = true;
00290
00291 if (NET_DEBUG)
00292 {
00293 cout << "net: couldn't bind UDP socket to host " << SDLNet_ResolveIP(&(pin->address)) << endl;
00294 printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError());
00295 }
00296 }
00297 WriteToPacket(pout, CONTROL_HANDSHAKE, (void *) handshake_reply.c_str(), handshake_reply.length());
00298 UDPSend(pout, 0);
00299 connected = true;
00300 if (NET_DEBUG)
00301 cout << "net: incoming connection established" << endl;
00302 }
00303 else
00304 {
00305 if (NET_DEBUG)
00306 cout << "net: Invalid handshake from " << SDLNet_ResolveIP(&(pin->address)) << endl;
00307 err = true;
00308 }
00309
00310 return err;
00311 }
00312
00313 void NET::Send(void * data, int size)
00314 {
00315 Uint8 * sourcedata = (Uint8 *) data;
00316
00317 if (pout == NULL)
00318 {
00319 if (NET_DEBUG)
00320 {
00321 cout << "net: Send: invalid packet" << endl;
00322 return;
00323 }
00324 }
00325
00326 if (size >= pout->maxlen)
00327 {
00328 if (NET_DEBUG)
00329 {
00330 cout << "net: Send: packet size is too large: " << size << endl;
00331 return;
00332 }
00333 }
00334
00335 pout->len = size;
00336
00337 int i;
00338 for (i = 0; i < size; i++)
00339 {
00340 pout->data[i] = sourcedata[i];
00341 }
00342
00343 UDPSend(pout, 0);
00344 }
00345
00346 int NET::RecvBlock(void * dest, int destsize, int timeout)
00347 {
00348 int r = UDPRecv(pin, 0, timeout);
00349
00350 Uint8 * destdata = (Uint8 *) dest;
00351
00352 if (r == UDP_SUCCESS)
00353 {
00354 int i;
00355 int mins = pin->len;
00356 if (destsize < mins)
00357 {
00358 mins = destsize;
00359 if (NET_DEBUG)
00360 cout << "net: RecvBlock: overflow (" << pin->len << ">" << destsize << endl;
00361 }
00362 for (i = 0; i < mins; i++)
00363 {
00364 destdata[i] = pin->data[i];
00365 }
00366 return mins;
00367 }
00368 else
00369 return r;
00370 }
00371
00372 void PBUFFER::Put(UDPpacket * newp)
00373 {
00374 valid = true;
00375
00376 if (data == NULL)
00377 data = new Uint8 [MAX_PACKET_SIZE];
00378
00379 int i;
00380 int mins = newp->len;
00381 if (MAX_PACKET_SIZE < mins)
00382 mins = MAX_PACKET_SIZE;
00383 for (i = 0; i < mins; i++)
00384 {
00385 data[i] = newp->data[i];
00386 }
00387
00388 len = mins;
00389
00390
00391
00392
00393
00394 }
00395
00396 int NET::BufferPacket(UDPpacket * newp)
00397 {
00398 datacounter_rx += newp->len;
00399
00400 int idx = -1;
00401 int i;
00402
00403 for (i = 0; idx < 0 && i < PACKET_BUFFER_LEN; i++)
00404 {
00405 if (!buffer[i].Valid())
00406 idx = i;
00407 }
00408
00409 if (idx >= 0)
00410 {
00411 buffer[idx].Put(newp);
00412 }
00413 else
00414 {
00415 if (NET_DEBUG)
00416 {
00417 cout << "net: BufferPacket: packet buffer is full, dropping packet!" << endl;
00418 }
00419 }
00420
00421 return idx;
00422 }
00423
00424 int NET::NumBufferedPackets()
00425 {
00426 int count = 0;
00427 int i;
00428 for (i = 0; i < PACKET_BUFFER_LEN; i++)
00429 if (buffer[i].Valid())
00430 count++;
00431
00432 return count;
00433 }