Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/network/udp_socket.cc @ 9319

Last change on this file since 9319 was 9319, checked in by patrick, 18 years ago

finaly found the client ip bug

File size: 6.4 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_socket.h"
17#include "udp_server_socket.h"
18#include "debug.h"
19
20
21void UdpSocket::init( )
22{
23  //TODO setClassId
24  this->serverSocket = NULL;
25  this->socket = NULL;
26  this->packet = NULL;
27  this->randomByte = 0;
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 );
40
41  assert( this->packet );
42
43  memset( packet->data, 0, UDP_PACKET_SIZE );
44  PRINTF(0)("PACKET DATA: %x\n", packet->data);
45
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 );
56
57  if ( !packet )
58  {
59    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
60
61    assert( false );
62    bOk = false;
63  }
64
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 */
73UdpSocket::UdpSocket( UdpServerSocket * serverSocket, IPaddress ip, int userId, byte randomByte )
74{
75  this->init();
76  this->ip = ip;
77  this->serverSocket = serverSocket;
78  this->userId = userId;
79  this->randomByte = randomByte;
80}
81
82/**
83 * destructor
84 */
85UdpSocket::~UdpSocket( )
86{
87  this->disconnectServer();
88
89  if ( serverSocket )
90    serverSocket->removeUser( userId );
91
92  if ( this->packet )
93    SDLNet_FreePacket( this->packet );
94
95  if ( socket )
96    SDLNet_UDP_Close( socket );
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 );
107
108  this->randomByte = generateNewRandomByte();
109
110  PRINTF(0)("connect to server %s on port %d\n", host.c_str(), port);
111
112  if ( SDLNet_ResolveHost( &this->ip, host.c_str(), port ) != 0 )
113  {
114    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError() );
115    bOk = false;
116    return;
117  }
118
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  }
126
127  int channel = SDLNet_UDP_Bind(socket, 1, &this->ip);
128  if ( channel == -1 )
129  {
130    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
131    bOk = false;
132    return;
133  }
134}
135
136/**
137 * disconnect from server
138 */
139void UdpSocket::disconnectServer( )
140{
141  PRINTF(0)("disconnect\n");
142  byte cmd = this->randomByte | UDPCMD_DISCONNECT;
143  writeRawPacket( &cmd, 1 );
144  SDLNet_UDP_Unbind( socket, -1 );
145  SDLNet_UDP_Close( socket );
146  bOk = false;
147  socket = NULL;
148
149  this->ip.host = 0;
150  this->ip.port = 0;
151}
152
153/**
154 * send one packet to other host
155 * @param data pointer to data which will be sent
156 * @param length length of data
157 * @return true on success
158 */
159bool UdpSocket::writePacket( byte * data, int length )
160{
161  byte * buf = new byte[length+1];
162  if ( length > 0 )
163    memcpy( buf+1, data, length );
164  buf[0] = this->randomByte;
165  return writeRawPacket( buf, length+1 );
166}
167
168/**
169 * recieve one packet from another host
170 * @param data pointer to buffer to copy data into
171 * @param maxLength maximal length of buffer
172 * @return less than 0 on error, number bytes read else
173 */
174int UdpSocket::readPacket( byte * data, int maxLength )
175{
176  assert( maxLength <= UDP_PACKET_SIZE );
177
178  if ( serverSocket )
179  {
180    NetworkPacket networkPacket = serverSocket->getPacket( this->userId );
181
182    byte udpCmd = 0;
183
184    if ( networkPacket.length > 0 )
185    {
186      assert( maxLength > networkPacket.length );
187
188      memcpy( data, networkPacket.data+1, networkPacket.length-1 );
189      udpCmd = networkPacket.data[0];
190    }
191    else
192      return 0;
193
194    if ( !checkRandomByte( networkPacket.data[0] ) )
195      return 0;
196
197    if ( networkPacket.data )
198    {
199      free( networkPacket.data );
200      networkPacket.data = NULL;
201    }
202
203    if ( !checkUdpCmd( udpCmd ) )
204      return 0;
205
206    return networkPacket.length-1;
207  }
208  else
209  {
210    int numrecv = SDLNet_UDP_Recv( socket, packet);
211
212    byte udpCmd = 0;
213
214    if ( numrecv > 0)
215    {
216      assert( packet->len <= maxLength );
217
218      if ( packet->len > 0 )
219        memcpy( data, packet->data+1, packet->len-1 );
220      else
221        return 0;
222
223      if ( !checkRandomByte( packet->data[0] ) )
224        return 0;
225
226      if ( !checkUdpCmd( udpCmd ) )
227        return 0;
228
229      return packet->len-1;
230    }
231    else if ( numrecv < 0 )
232    {
233      PRINTF(1)("SDLNet_UDP_Recv: %s\n", SDLNet_GetError());
234      bOk = false;
235      return -1;
236    }
237    else
238    {
239      return 0;
240    }
241  }
242
243  return 0;
244}
245
246bool UdpSocket::writeRawPacket( byte * data, int length )
247{
248  if ( serverSocket )
249  {
250    NetworkPacket networkPacket;
251    networkPacket.length = length;
252    networkPacket.data = data;
253    if ( !serverSocket->sendPacket( networkPacket, this->userId ) )
254    {
255      bOk = false;
256      return false;
257    }
258    else
259      return true;
260  }
261  else
262  {
263    assert( length <= packet->maxlen );
264
265    memcpy( packet->data, data, length );
266    packet->len = length;
267
268    if ( socket && SDLNet_UDP_Send( socket, 1, packet) == 0 )
269    {
270      PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
271      bOk = false;
272      return false;
273    }
274
275    return true;
276  }
277}
278
279bool UdpSocket::checkUdpCmd( byte udpCmd )
280{
281  if ( udpCmd & UDPCMD_DISCONNECT )
282  {
283    this->disconnectServer();
284    PRINTF(0)("received disconnect byte\n");
285    return false;
286  }
287
288  if ( !this->serverSocket && ( udpCmd & UDPCMD_INVALIDRNDBYTE ) )
289  {
290    PRINTF(0)("received invlid random number byte\n");
291    byte cmd = this->randomByte | UDPCMD_DISCONNECT;
292    writeRawPacket( &cmd, 1 );
293    this->randomByte = generateNewRandomByte();
294    return false;
295  }
296
297  return true;
298}
299
300byte UdpSocket::generateNewRandomByte( )
301{
302  srand( SDL_GetTicks() );
303  byte res = ( rand() & 0xFC );
304
305  PRINTF(0)("generated random byte: %x\n", res);
306
307  return res;
308}
309
310bool UdpSocket::checkRandomByte( byte rndByte )
311{
312  if ( ( rndByte & 0xFC ) == this->randomByte )
313  {
314    return true;
315  }
316  else
317  {
318    PRINTF(2)("wrong random byte: %x\n", ( rndByte & 0xFC ));
319    return false;
320  }
321}
322
323
324
Note: See TracBrowser for help on using the repository browser.