Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

implemented udp sockets

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