Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added some output to udp sockets

File size: 6.0 KB
Line 
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"
17
18
19
20/**
21 * constructor
22 * @param port port to listen on
23 */
24UdpServerSocket::UdpServerSocket( int port ) : ServerSocket( port )
25{
26  packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
27 
28  if ( !packet )
29  {
30    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
31   
32    assert( false );
33    bOk = false;
34  }
35 
36  listen( port );
37}
38
39/**
40 * default destructor
41 */
42UdpServerSocket::~UdpServerSocket( )
43{
44  for ( int i = 0; i < packetBuffer.size(); i++ )
45    removeUserPackets( i );
46 
47  if ( packet )
48    SDLNet_FreePacket( packet );
49 
50  if ( socket )
51    SDLNet_UDP_Close( socket );
52}
53
54/**
55 * tell udpServerSocket to recieve packets on port
56 * @param port port
57 * @return true on success
58 */
59bool UdpServerSocket::listen( unsigned int port )
60{
61  socket = SDLNet_UDP_Open( port );
62 
63  PRINTF(0)("listening on port: %d\n", port);
64 
65  if ( !socket )
66  {
67   
68    bOk = false;
69    return false;
70  }
71 
72  return true;
73}
74
75/**
76 * get newly connected socket. note
77 * @return new socket or NULL if no new socket exists
78 */
79NetworkSocket * UdpServerSocket::getNewSocket( void )
80{
81  NetworkSocket * result = NULL;
82 
83  if ( newSocketList.size() > 0 )
84  {
85    result = newSocketList.front();
86 
87    newSocketList.pop_front();
88  }
89 
90  return result;
91}
92
93/**
94 * stop listening on server
95 */
96void UdpServerSocket::close( )
97{
98 
99  for ( int i = 0; i < packetBuffer.size(); i++ )
100    removeUserPackets( i );
101 
102  packetBuffer.clear();
103  userList.clear();
104 
105  SDLNet_UDP_Close( socket );
106  socket = NULL;
107}
108
109/**
110 * clean up users buffer
111 * @param userId users userid
112 */
113void UdpServerSocket::removeUserPackets( int userId )
114{
115  if ( userId >= packetBuffer.size() )
116    return;
117 
118  for ( NetworkPacketList::iterator it = packetBuffer[userId].begin(); it!=packetBuffer[userId].end(); it++ )
119  {
120    if ( it->data )
121    {
122      free( it->data );
123      it->data = NULL;
124    }
125  }
126 
127  packetBuffer[userId].clear();
128}
129
130/**
131 * get next packet for user
132 * @param userId user id
133 * @return recieved packet or packet with length 0 if no packet available
134 */
135NetworkPacket UdpServerSocket::getPacket( int userId )
136{
137  NetworkPacket res;
138  res.data = NULL;
139  res.length = 0;
140 
141  if ( packetBuffer.size() > userId && packetBuffer[userId].size() > 0 )
142  {
143    res.data = packetBuffer[userId].front().data;
144    res.length = packetBuffer[userId].front().length;
145    packetBuffer[userId].pop_front();
146  }
147 
148  return res;
149}
150
151/**
152 * get number of packets recieved for user
153 * @param userId user id
154 * @return number of packets in buffer
155 */
156int UdpServerSocket::getPacketCount( int userId )
157{
158  if ( userId >= packetBuffer.size() )
159    return -1;
160 
161  return packetBuffer[userId].size();
162}
163
164/**
165 * will set user state
166 * @param userId users id
167 * @param ip users host / port
168 */
169void UdpServerSocket::initUser( int userId, IPaddress ip )
170{
171  int channel = SDLNet_UDP_Bind( socket, userId, &ip );
172  if( channel != userId ) 
173  {
174    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
175    assert(false);
176    return;
177  }
178 
179  if ( userId < packetBuffer.size() )
180    removeUserPackets( userId );
181 
182  if ( packetBuffer.size() <= userId )
183    packetBuffer.resize( userId + 1 );
184 
185  if ( userList.size() <= userId )
186    userList.resize( userId + 1 );
187 
188  userList[ userId ] = ip;
189}
190
191/**
192 * remove user from list
193 * @param userId user id
194 */
195void UdpServerSocket::removeUser( int userId )
196{
197  removeUserPackets( userId );
198 
199  if ( userId >= userList.size() )
200    return;
201 
202  userList[userId].host = 0;
203  userList[userId].port = 0;
204 
205  SDLNet_UDP_Unbind( socket, userId );
206}
207
208/**
209 * send one packet to client associated to userId
210 * @param networkPacket packet to send
211 * @param userId users id
212 * @return true on success
213 */
214bool UdpServerSocket::sendPacket( NetworkPacket networkPacket , int userId )
215{
216  assert( networkPacket.length <= UDP_PACKET_SIZE );
217 
218  memcpy( packet->data, networkPacket.data, networkPacket.length );
219  packet->len = networkPacket.length;
220  packet->channel = -1;
221 
222  if ( SDLNet_UDP_Send( socket, userId, packet ) == 0 )
223  {
224    PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
225    return false;
226  }
227 
228  return true;
229}
230
231/**
232 * do periodically things
233 */
234void UdpServerSocket::update( )
235{
236  int res;
237  int newConn = 0;
238 
239  for ( res = SDLNet_UDP_Recv( socket, packet ); res == 1; res = SDLNet_UDP_Recv( socket, packet ) )
240  {
241    int userId;
242    bool isNewConnection = false;
243   
244    for ( userId =0; userId < userList.size(); userId++ )
245      if ( userList[userId].host == packet->address.host && userList[userId].port == packet->address.port )
246        break;
247   
248    if ( userId >= userList.size() )
249    {
250      newConn++;
251      isNewConnection = true;
252     
253      if ( newConn > MAX_NEW_CONNECTIONS )
254      {
255        PRINTF(2)("Too many new connections. Dropping packet\n");
256        continue;
257      }
258     
259      for ( userId =0; userId < userList.size(); userId++ )
260        if ( userList[userId].host == 0 && userList[userId].port == 0 )
261          break;
262     
263      initUser( userId, packet->address );
264      UdpSocket * sock = new UdpSocket( this, packet->address, userId );
265      newSocketList.push_back( sock );
266      PRINTF(0)("NEW CONNECTION %x\n", packet->address.host );
267    }
268   
269    //add new packet to packetbuffer
270    NetworkPacket networkPacket;
271    networkPacket.length = packet->len;
272    if ( packet->len != 0 )
273    {
274      networkPacket.data = (byte*)malloc( packet->len );
275      assert( networkPacket.data );
276    }
277    else
278    {
279      if ( isNewConnection )
280        continue;
281     
282      networkPacket.data = NULL;
283    }
284    memcpy( networkPacket.data, packet->data, packet->len );
285    packetBuffer[userId].push_back( networkPacket );
286  }
287 
288  assert( res == 0 );
289}
Note: See TracBrowser for help on using the repository browser.