Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/udp_server_socket.cc

Last change on this file was 9869, checked in by bensch, 18 years ago

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

File size: 6.5 KB
RevLine 
[7540]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Christoph Renner
13   co-programmer:
14*/
15
16#include "udp_server_socket.h"
[8362]17#include "debug.h"
[7540]18
19
[9869]20ObjectListDefinition(UdpServerSocket);
[7540]21/**
22 * constructor
[8362]23 * @param port port to listen on
[7540]24 */
25UdpServerSocket::UdpServerSocket( int port ) : ServerSocket( port )
26{
27  packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
[8362]28
[7540]29  if ( !packet )
30  {
31    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
[8362]32
[7540]33    assert( false );
34    bOk = false;
35  }
[8362]36
[7613]37  memset( packet->data, 0, UDP_PACKET_SIZE );
[8362]38
[7540]39  listen( port );
40}
41
42/**
43 * default destructor
44 */
45UdpServerSocket::~UdpServerSocket( )
46{
[8228]47  for ( int i = 0; i < (int)packetBuffer.size(); i++ )
[7540]48    removeUserPackets( i );
[8362]49
[7556]50  if ( packet )
51    SDLNet_FreePacket( packet );
[8362]52
[7556]53  if ( socket )
54    SDLNet_UDP_Close( socket );
[7540]55}
56
57/**
58 * tell udpServerSocket to recieve packets on port
59 * @param port port
60 * @return true on success
61 */
62bool UdpServerSocket::listen( unsigned int port )
63{
64  socket = SDLNet_UDP_Open( port );
[8362]65
[7570]66  PRINTF(0)("listening on port: %d\n", port);
[8362]67
[7540]68  if ( !socket )
69  {
[8362]70
[7540]71    bOk = false;
72    return false;
73  }
[8362]74
[7540]75  return true;
76}
77
78/**
[7565]79 * get newly connected socket. note
[7540]80 * @return new socket or NULL if no new socket exists
81 */
82NetworkSocket * UdpServerSocket::getNewSocket( void )
83{
[7553]84  NetworkSocket * result = NULL;
[8362]85
[7553]86  if ( newSocketList.size() > 0 )
87  {
88    result = newSocketList.front();
[8362]89
[7553]90    newSocketList.pop_front();
91  }
[8362]92
[7540]93  return result;
94}
95
[9494]96
[7540]97/**
98 * stop listening on server
99 */
100void UdpServerSocket::close( )
101{
[8362]102
[8228]103  for ( int i = 0; i < (int)packetBuffer.size(); i++ )
[7540]104    removeUserPackets( i );
[8362]105
[7540]106  packetBuffer.clear();
107  userList.clear();
[8362]108
[7540]109  SDLNet_UDP_Close( socket );
110  socket = NULL;
111}
112
113/**
114 * clean up users buffer
115 * @param userId users userid
116 */
117void UdpServerSocket::removeUserPackets( int userId )
118{
[8228]119  if ( userId >= (int)packetBuffer.size() )
[7540]120    return;
[8362]121
[7540]122  for ( NetworkPacketList::iterator it = packetBuffer[userId].begin(); it!=packetBuffer[userId].end(); it++ )
123  {
124    if ( it->data )
125    {
[7556]126      free( it->data );
[7540]127      it->data = NULL;
128    }
129  }
[8362]130
[7540]131  packetBuffer[userId].clear();
132}
133
134/**
135 * get next packet for user
136 * @param userId user id
137 * @return recieved packet or packet with length 0 if no packet available
138 */
139NetworkPacket UdpServerSocket::getPacket( int userId )
140{
141  NetworkPacket res;
142  res.data = NULL;
143  res.length = 0;
[8362]144
[8228]145  if ( (int)packetBuffer.size() > userId && (int)packetBuffer[userId].size() > 0 )
[7540]146  {
147    res.data = packetBuffer[userId].front().data;
148    res.length = packetBuffer[userId].front().length;
149    packetBuffer[userId].pop_front();
150  }
[8362]151
[7540]152  return res;
153}
154
155/**
156 * get number of packets recieved for user
157 * @param userId user id
158 * @return number of packets in buffer
159 */
160int UdpServerSocket::getPacketCount( int userId )
161{
[8228]162  if ( userId >= (int)packetBuffer.size() )
[7540]163    return -1;
[8362]164
[7540]165  return packetBuffer[userId].size();
166}
167
168/**
[8362]169 * will set user state
[7540]170 * @param userId users id
171 * @param ip users host / port
172 */
[8802]173void UdpServerSocket::initUser( int userId, IPaddress ip, byte randomByte )
[7540]174{
175  int channel = SDLNet_UDP_Bind( socket, userId, &ip );
[8362]176  if( channel != userId )
[7540]177  {
178    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
179    assert(false);
180    return;
181  }
[8362]182
[8228]183  if ( userId < (int)packetBuffer.size() )
[7540]184    removeUserPackets( userId );
[8362]185
[8228]186  if ( (int)packetBuffer.size() <= userId )
[7540]187    packetBuffer.resize( userId + 1 );
[8362]188
[8228]189  if ( (int)userList.size() <= userId )
[7540]190    userList.resize( userId + 1 );
[8362]191
[8802]192  userList[ userId ].addr = ip;
193  userList[ userId ].randomByte = randomByte;
[7540]194}
195
196/**
197 * remove user from list
198 * @param userId user id
199 */
200void UdpServerSocket::removeUser( int userId )
201{
202  removeUserPackets( userId );
[8362]203
[8228]204  if ( userId >= (int)userList.size() )
[7540]205    return;
[8362]206
[8802]207  userList[userId].addr.host = 0;
208  userList[userId].addr.port = 0;
[8362]209
[7540]210  SDLNet_UDP_Unbind( socket, userId );
211}
212
213/**
214 * send one packet to client associated to userId
215 * @param networkPacket packet to send
216 * @param userId users id
217 * @return true on success
218 */
219bool UdpServerSocket::sendPacket( NetworkPacket networkPacket , int userId )
220{
[8623]221  if ( !socket )
222    return false;
[9494]223
[7540]224  assert( networkPacket.length <= UDP_PACKET_SIZE );
[8362]225
[7540]226  memcpy( packet->data, networkPacket.data, networkPacket.length );
227  packet->len = networkPacket.length;
[7556]228  packet->channel = -1;
[8362]229
[7540]230  if ( SDLNet_UDP_Send( socket, userId, packet ) == 0 )
231  {
232    PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
233    return false;
234  }
[9494]235
[7540]236  return true;
237}
[7565]238
239/**
240 * do periodically things
241 */
242void UdpServerSocket::update( )
243{
244  int res;
245  int newConn = 0;
[8362]246
[9494]247  // iterate through all newly received packets and assign them to the users packet buffer
[7565]248  for ( res = SDLNet_UDP_Recv( socket, packet ); res == 1; res = SDLNet_UDP_Recv( socket, packet ) )
249  {
250    int userId;
251    bool isNewConnection = false;
[8362]252
[8802]253    if ( packet->len <= 0 )
[9494]254      continue;
255
256    // search the user id this backet belongs to
257    for ( userId = 0; userId < (int)userList.size(); userId++ )
258    {
259      if ( userList[userId].addr.host == packet->address.host &&
260           userList[userId].addr.port == packet->address.port &&
261           userList[userId].randomByte == ( packet->data[0] & 0xFC ) )
[7565]262        break;
[9494]263    }
[8362]264
[9494]265    // is it a new packet initializing a new connecion?
[8228]266    if ( userId >= (int)userList.size() )
[7565]267    {
268      newConn++;
269      isNewConnection = true;
[8362]270
[7565]271      if ( newConn > MAX_NEW_CONNECTIONS )
272      {
273        PRINTF(2)("Too many new connections. Dropping packet\n");
274        continue;
275      }
[8362]276
[8228]277      for ( userId =0; userId < (int)userList.size(); userId++ )
[8802]278        if ( userList[userId].addr.host == 0 && userList[userId].addr.port == 0 )
[7565]279          break;
[8362]280
[9494]281      this->initUser( userId, packet->address, packet->data[0] & 0xFC );
[8802]282      UdpSocket * sock = new UdpSocket( this, packet->address, userId, packet->data[0] & 0xFC );
[7565]283      newSocketList.push_back( sock );
284      PRINTF(0)("NEW CONNECTION %x\n", packet->address.host );
285    }
[8362]286
[7854]287
[9494]288    // add new packet to packetbuffer
[7565]289    NetworkPacket networkPacket;
290    networkPacket.length = packet->len;
291    if ( packet->len != 0 )
292    {
293      networkPacket.data = (byte*)malloc( packet->len );
294      assert( networkPacket.data );
295    }
296    else
297    {
298      networkPacket.data = NULL;
299    }
300    memcpy( networkPacket.data, packet->data, packet->len );
301    packetBuffer[userId].push_back( networkPacket );
302  }
[8362]303
[7565]304  assert( res == 0 );
305}
Note: See TracBrowser for help on using the repository browser.