Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/udp_socket.cc @ 9571

Last change on this file since 9571 was 9406, checked in by bensch, 18 years ago

orxonox/trunk: merged the proxy back

merged with commandsvn merge -r9346:HEAD https://svn.orxonox.net/orxonox/branches/proxy .

no conflicts

File size: 7.0 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_socket.h"
17#include "udp_server_socket.h"
[8362]18#include "debug.h"
[7540]19
20
21void UdpSocket::init( )
22{
[7541]23  //TODO setClassId
[7540]24  this->serverSocket = NULL;
25  this->socket = NULL;
26  this->packet = NULL;
[8802]27  this->randomByte = 0;
[7540]28}
29
30
31/**
32 * constructor - connects to give host
33 * @param host host
34 * @param port port
35 */
36UdpSocket::UdpSocket( std::string host, int port )
37{
38  init();
39  this->packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
[8362]40
[7613]41  assert( this->packet );
[8362]42
[7613]43  memset( packet->data, 0, UDP_PACKET_SIZE );
44  PRINTF(0)("PACKET DATA: %x\n", packet->data);
[8362]45
[7540]46  this->connectToServer( host, port );
47}
48
49/**
50 * default constructor. use this one if you want to call connecttoServer
51 */
52UdpSocket::UdpSocket( )
53{
54  this->init();
55  this->packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
[8362]56
[7540]57  if ( !packet )
58  {
59    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
[8362]60
[7540]61    assert( false );
62    bOk = false;
63  }
[8362]64
[7540]65}
66
67/**
68 * constructor. used by UdpServerSocket
69 * @param serverSocket pointer to serverSocket
70 * @param ip client's ip address
71 * @param userId userid used by serverSocket
72 */
[8802]73UdpSocket::UdpSocket( UdpServerSocket * serverSocket, IPaddress ip, int userId, byte randomByte )
[7540]74{
75  this->init();
[9406]76  this->ip = ip;
[7540]77  this->serverSocket = serverSocket;
[7556]78  this->userId = userId;
[8802]79  this->randomByte = randomByte;
[7540]80}
81
82/**
83 * destructor
84 */
[7556]85UdpSocket::~UdpSocket( )
[7540]86{
[8228]87  this->disconnectServer();
[8362]88
[7540]89  if ( serverSocket )
90    serverSocket->removeUser( userId );
[8228]91
[7556]92  if ( this->packet )
93    SDLNet_FreePacket( this->packet );
[8362]94
[7556]95  if ( socket )
96    SDLNet_UDP_Close( socket );
[7540]97}
98
99/**
100 * connect to server
101 * @param host host name
102 * @param port port number
103 */
104void UdpSocket::connectToServer( std::string host, int port )
105{
106  assert( serverSocket == NULL );
[8362]107
[8802]108  this->randomByte = generateNewRandomByte();
[8362]109
[7570]110  PRINTF(0)("connect to server %s on port %d\n", host.c_str(), port);
[8362]111
[9406]112  if ( SDLNet_ResolveHost( &this->ip, host.c_str(), port ) != 0 )
[7540]113  {
114    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError() );
115    bOk = false;
116    return;
117  }
[8362]118
[7540]119  socket = SDLNet_UDP_Open(0);
120  if ( !socket )
121  {
122    PRINTF(1)("SDLNet_UDP_Open: %s\n", SDLNet_GetError() );
123    bOk = false;
124    return;
125  }
[8362]126
[9406]127  int channel = SDLNet_UDP_Bind(socket, 1, &this->ip);
[8362]128  if ( channel == -1 )
[7540]129  {
[7872]130    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
[7540]131    bOk = false;
132    return;
133  }
134}
135
136/**
137 * disconnect from server
138 */
139void UdpSocket::disconnectServer( )
140{
[8228]141  PRINTF(0)("disconnect\n");
[8802]142  byte cmd = this->randomByte | UDPCMD_DISCONNECT;
143  writeRawPacket( &cmd, 1 );
[7540]144  SDLNet_UDP_Unbind( socket, -1 );
145  SDLNet_UDP_Close( socket );
[7565]146  bOk = false;
[7540]147  socket = NULL;
[9406]148
149  this->ip.host = 0;
150  this->ip.port = 0;
[7540]151}
152
[9406]153
[7540]154/**
[9406]155 * reconnects to
156 * @param host new server address
157 * @param port new port number
158 *
159 * this terminates the current connection and starts a new connection to the new server
160 */
161void UdpSocket::reconnectToServer( std::string host, int port)
162{
163  // first disconnect the old server
164  this->disconnectServer();
165
166  // now connect to the new
167  this->connectToServer( host, port);
168}
169
170
171/**
172 * reconnects to
173 * @param host new server address
174 * @param port new port number
175 *
176 * this terminates the current connection and starts a new connection to the new server
177 */
178void UdpSocket::reconnectToServerSoft( std::string host, int port)
179{}
180
181
182/**
[7540]183 * send one packet to other host
184 * @param data pointer to data which will be sent
185 * @param length length of data
186 * @return true on success
187 */
188bool UdpSocket::writePacket( byte * data, int length )
189{
[8802]190  byte * buf = new byte[length+1];
191  if ( length > 0 )
192    memcpy( buf+1, data, length );
193  buf[0] = this->randomByte;
194  return writeRawPacket( buf, length+1 );
[7540]195}
196
197/**
198 * recieve one packet from another host
199 * @param data pointer to buffer to copy data into
200 * @param maxLength maximal length of buffer
201 * @return less than 0 on error, number bytes read else
202 */
203int UdpSocket::readPacket( byte * data, int maxLength )
204{
[7565]205  assert( maxLength <= UDP_PACKET_SIZE );
[8362]206
[7540]207  if ( serverSocket )
208  {
209    NetworkPacket networkPacket = serverSocket->getPacket( this->userId );
[8362]210
[8802]211    byte udpCmd = 0;
[9406]212
[7540]213    if ( networkPacket.length > 0 )
214    {
215      assert( maxLength > networkPacket.length );
[8362]216
[8802]217      memcpy( data, networkPacket.data+1, networkPacket.length-1 );
218      udpCmd = networkPacket.data[0];
[7540]219    }
[8802]220    else
221      return 0;
[9406]222
[8802]223    if ( !checkRandomByte( networkPacket.data[0] ) )
224      return 0;
[8362]225
[7540]226    if ( networkPacket.data )
227    {
[7556]228      free( networkPacket.data );
[7540]229      networkPacket.data = NULL;
230    }
[9406]231
[8802]232    if ( !checkUdpCmd( udpCmd ) )
233      return 0;
[8362]234
[8802]235    return networkPacket.length-1;
[7540]236  }
237  else
238  {
239    int numrecv = SDLNet_UDP_Recv( socket, packet);
[9406]240
[8802]241    byte udpCmd = 0;
242
[8362]243    if ( numrecv > 0)
[7540]244    {
245      assert( packet->len <= maxLength );
[8362]246
[8802]247      if ( packet->len > 0 )
248        memcpy( data, packet->data+1, packet->len-1 );
249      else
[8228]250        return 0;
[9406]251
[8802]252      if ( !checkRandomByte( packet->data[0] ) )
253        return 0;
[9406]254
[8802]255      if ( !checkUdpCmd( udpCmd ) )
256        return 0;
[8362]257
[8802]258      return packet->len-1;
[7540]259    }
260    else if ( numrecv < 0 )
261    {
262      PRINTF(1)("SDLNet_UDP_Recv: %s\n", SDLNet_GetError());
263      bOk = false;
264      return -1;
265    }
266    else
267    {
268      return 0;
269    }
270  }
[8362]271
[7540]272  return 0;
273}
274
[8802]275bool UdpSocket::writeRawPacket( byte * data, int length )
276{
277  if ( serverSocket )
278  {
279    NetworkPacket networkPacket;
280    networkPacket.length = length;
281    networkPacket.data = data;
282    if ( !serverSocket->sendPacket( networkPacket, this->userId ) )
283    {
284      bOk = false;
285      return false;
286    }
287    else
288      return true;
289  }
290  else
291  {
292    assert( length <= packet->maxlen );
[7540]293
[8802]294    memcpy( packet->data, data, length );
295    packet->len = length;
[7540]296
[8802]297    if ( socket && SDLNet_UDP_Send( socket, 1, packet) == 0 )
298    {
299      PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
300      bOk = false;
301      return false;
302    }
303
304    return true;
305  }
306}
307
308bool UdpSocket::checkUdpCmd( byte udpCmd )
309{
310  if ( udpCmd & UDPCMD_DISCONNECT )
311  {
312    this->disconnectServer();
313    PRINTF(0)("received disconnect byte\n");
314    return false;
315  }
[9406]316
[8802]317  if ( !this->serverSocket && ( udpCmd & UDPCMD_INVALIDRNDBYTE ) )
318  {
319    PRINTF(0)("received invlid random number byte\n");
320    byte cmd = this->randomByte | UDPCMD_DISCONNECT;
321    writeRawPacket( &cmd, 1 );
322    this->randomByte = generateNewRandomByte();
323    return false;
324  }
[9406]325
[8802]326  return true;
327}
328
329byte UdpSocket::generateNewRandomByte( )
330{
331  srand( SDL_GetTicks() );
332  byte res = ( rand() & 0xFC );
[9406]333
[8802]334  PRINTF(0)("generated random byte: %x\n", res);
[9406]335
[8802]336  return res;
337}
338
339bool UdpSocket::checkRandomByte( byte rndByte )
340{
341  if ( ( rndByte & 0xFC ) == this->randomByte )
342  {
343    return true;
344  }
345  else
346  {
347    PRINTF(2)("wrong random byte: %x\n", ( rndByte & 0xFC ));
348    return false;
349  }
350}
351
352
353
Note: See TracBrowser for help on using the repository browser.