Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/network/udp_socket.cc @ 9690

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

some network-stuff

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