Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/lib/network/udp_server_socket.cc @ 8727

Last change on this file since 8727 was 8727, checked in by rennerc, 18 years ago

server identifies user by his random byte

File size: 6.3 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
20
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
96/**
97 * stop listening on server
98 */
99void UdpServerSocket::close( )
100{
[8362]101
[8228]102  for ( int i = 0; i < (int)packetBuffer.size(); i++ )
[7540]103    removeUserPackets( i );
[8362]104
[7540]105  packetBuffer.clear();
106  userList.clear();
[8362]107
[7540]108  SDLNet_UDP_Close( socket );
109  socket = NULL;
110}
111
112/**
113 * clean up users buffer
114 * @param userId users userid
115 */
116void UdpServerSocket::removeUserPackets( int userId )
117{
[8228]118  if ( userId >= (int)packetBuffer.size() )
[7540]119    return;
[8362]120
[7540]121  for ( NetworkPacketList::iterator it = packetBuffer[userId].begin(); it!=packetBuffer[userId].end(); it++ )
122  {
123    if ( it->data )
124    {
[7556]125      free( it->data );
[7540]126      it->data = NULL;
127    }
128  }
[8362]129
[7540]130  packetBuffer[userId].clear();
131}
132
133/**
134 * get next packet for user
135 * @param userId user id
136 * @return recieved packet or packet with length 0 if no packet available
137 */
138NetworkPacket UdpServerSocket::getPacket( int userId )
139{
140  NetworkPacket res;
141  res.data = NULL;
142  res.length = 0;
[8362]143
[8228]144  if ( (int)packetBuffer.size() > userId && (int)packetBuffer[userId].size() > 0 )
[7540]145  {
146    res.data = packetBuffer[userId].front().data;
147    res.length = packetBuffer[userId].front().length;
148    packetBuffer[userId].pop_front();
149  }
[8362]150
[7540]151  return res;
152}
153
154/**
155 * get number of packets recieved for user
156 * @param userId user id
157 * @return number of packets in buffer
158 */
159int UdpServerSocket::getPacketCount( int userId )
160{
[8228]161  if ( userId >= (int)packetBuffer.size() )
[7540]162    return -1;
[8362]163
[7540]164  return packetBuffer[userId].size();
165}
166
167/**
[8362]168 * will set user state
[7540]169 * @param userId users id
170 * @param ip users host / port
171 */
[8727]172void UdpServerSocket::initUser( int userId, IPaddress ip, byte randomByte )
[7540]173{
174  int channel = SDLNet_UDP_Bind( socket, userId, &ip );
[8362]175  if( channel != userId )
[7540]176  {
177    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
178    assert(false);
179    return;
180  }
[8362]181
[8228]182  if ( userId < (int)packetBuffer.size() )
[7540]183    removeUserPackets( userId );
[8362]184
[8228]185  if ( (int)packetBuffer.size() <= userId )
[7540]186    packetBuffer.resize( userId + 1 );
[8362]187
[8228]188  if ( (int)userList.size() <= userId )
[7540]189    userList.resize( userId + 1 );
[8362]190
[8727]191  userList[ userId ].addr = ip;
192  userList[ userId ].randomByte = randomByte;
[7540]193}
194
195/**
196 * remove user from list
197 * @param userId user id
198 */
199void UdpServerSocket::removeUser( int userId )
200{
201  removeUserPackets( userId );
[8362]202
[8228]203  if ( userId >= (int)userList.size() )
[7540]204    return;
[8362]205
[8727]206  userList[userId].addr.host = 0;
207  userList[userId].addr.port = 0;
[8362]208
[7540]209  SDLNet_UDP_Unbind( socket, userId );
210}
211
212/**
213 * send one packet to client associated to userId
214 * @param networkPacket packet to send
215 * @param userId users id
216 * @return true on success
217 */
218bool UdpServerSocket::sendPacket( NetworkPacket networkPacket , int userId )
219{
[8623]220  if ( !socket )
221    return false;
222 
[7540]223  assert( networkPacket.length <= UDP_PACKET_SIZE );
[8362]224
[7540]225  memcpy( packet->data, networkPacket.data, networkPacket.length );
226  packet->len = networkPacket.length;
[7556]227  packet->channel = -1;
[8362]228
[7540]229  if ( SDLNet_UDP_Send( socket, userId, packet ) == 0 )
230  {
231    PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
232    return false;
233  }
[8723]234 
[7540]235  return true;
236}
[7565]237
238/**
239 * do periodically things
240 */
241void UdpServerSocket::update( )
242{
243  int res;
244  int newConn = 0;
[8362]245
[7565]246  for ( res = SDLNet_UDP_Recv( socket, packet ); res == 1; res = SDLNet_UDP_Recv( socket, packet ) )
247  {
248    int userId;
249    bool isNewConnection = false;
[8362]250
[8727]251    if ( packet->len <= 0 )
252      continue; 
253       
[8228]254    for ( userId =0; userId < (int)userList.size(); userId++ )
[8727]255      if ( userList[userId].addr.host == packet->address.host && userList[userId].addr.port == packet->address.port && userList[userId].randomByte == ( packet->data[0] & 0xFC ) )
[7565]256        break;
[8362]257
[8228]258    if ( userId >= (int)userList.size() )
[7565]259    {
260      newConn++;
261      isNewConnection = true;
[8362]262
[7565]263      if ( newConn > MAX_NEW_CONNECTIONS )
264      {
265        PRINTF(2)("Too many new connections. Dropping packet\n");
266        continue;
267      }
[8362]268
[8228]269      for ( userId =0; userId < (int)userList.size(); userId++ )
[8727]270        if ( userList[userId].addr.host == 0 && userList[userId].addr.port == 0 )
[7565]271          break;
[8362]272
[8727]273      initUser( userId, packet->address, packet->data[0] & 0xFC );
[8723]274      UdpSocket * sock = new UdpSocket( this, packet->address, userId, packet->data[0] & 0xFC );
[7565]275      newSocketList.push_back( sock );
276      PRINTF(0)("NEW CONNECTION %x\n", packet->address.host );
277    }
[8362]278
[7565]279    //add new packet to packetbuffer
[7854]280
[7565]281    NetworkPacket networkPacket;
282    networkPacket.length = packet->len;
283    if ( packet->len != 0 )
284    {
285      networkPacket.data = (byte*)malloc( packet->len );
286      assert( networkPacket.data );
287    }
288    else
289    {
290      networkPacket.data = NULL;
291    }
292    memcpy( networkPacket.data, packet->data, packet->len );
293    packetBuffer[userId].push_back( networkPacket );
294  }
[8362]295
[7565]296  assert( res == 0 );
297}
Note: See TracBrowser for help on using the repository browser.