src/net.cpp

Go to the documentation of this file.
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         //try a handshake
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         /*if (remote_socket != NULL)
00097                 return true;
00098         else
00099                 return false;*/
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 //this function assumes pin already has an incoming packet from the client
00276 bool NET::ServerHandshake()
00277 {
00278         string handshake = HANDSHAKESTR;
00279         string handshake_reply = HANDSHAKEREPLYSTR;
00280 //      int timeout = HANDSHAKETIMEOUT;
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         /*packet->channel = newp->channel;
00391         packet->len = newp->len;
00392         packet->status = newp->status;
00393         packet->address = newp->address;*/
00394 }
00395 
00396 int NET::BufferPacket(UDPpacket * newp)
00397 {
00398         datacounter_rx += newp->len;
00399         
00400         int idx = -1;
00401         int i;
00402         //find a free buffer slot
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 }

Generated on Thu Oct 19 04:05:54 2006 by  doxygen 1.4.6