Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/lib/network/network_stream.cc @ 6043

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

added handshake

File size: 9.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: claudio
13   co-programmer:
14*/
15
16
17/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
18   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
19*/
20#define DEBUG_MODULE_NETWORK
21
22
23#include "base_object.h"
24#include "network_protocol.h"
25#include "network_socket.h"
26#include "connection_monitor.h"
27#include "synchronizeable.h"
28#include "network_manager.h"
29#include "list.h"
30#include "debug.h"
31
32/* include your own header */
33#include "network_stream.h"
34
35/* probably unnecessary */
36using namespace std;
37
38
39#define PACKAGE_SIZE  256
40
41
42NetworkStream::NetworkStream()
43    : DataStream()
44{
45  this->init();
46  /* initialize the references */
47  this->type = NET_CLIENT;
48  this->networkProtocol = new NetworkProtocol();
49  this->connectionMonitor = new ConnectionMonitor();
50}
51
52NetworkStream::NetworkStream(IPaddress& address)
53{
54  this->type = NET_CLIENT;
55  this->init();
56  this->networkSockets.push_back(new NetworkSocket(address));
57  this->networkProtocol = new NetworkProtocol();
58  this->connectionMonitor = new ConnectionMonitor();
59
60  Handshake* hs = new Handshake(false);
61  this->handshakes.push_back(hs);
62  this->connectSynchronizeable(*hs);
63  PRINTF(0)("NetworkStream: %s\n", hs->getName());
64}
65
66
67NetworkStream::NetworkStream(unsigned int port)
68{
69  this->type = NET_SERVER;
70  this->init();
71  this->serverSocket = new ServerSocket(port);
72  this->networkProtocol = new NetworkProtocol();
73  this->connectionMonitor = new ConnectionMonitor();
74  this->networkSockets.push_back( NULL );
75  this->bActive = true;
76}
77
78
79void NetworkStream::init()
80{
81  /* set the class id for the base object */
82  this->setClassID(CL_NETWORK_STREAM, "NetworkStream");
83  this->bActive = false;
84  this->serverSocket = NULL;
85  myHostId = 0;
86}
87
88
89NetworkStream::~NetworkStream()
90{
91  if ( this->serverSocket )
92  {
93    serverSocket->close();
94    delete serverSocket;
95  }
96
97  for (NetworkSocketVector::iterator i = networkSockets.begin(); i!=networkSockets.end(); i++)
98  {
99    if ( *i )
100    {
101      (*i)->disconnectServer();
102      (*i)->destroy();
103    }
104  }
105
106  for (HandshakeVector::iterator i = handshakes.begin(); i!=handshakes.end(); i++)
107  {
108    if ( *i )
109    {
110      delete (*i);
111    }
112  }
113
114  delete connectionMonitor;
115  delete networkProtocol;
116}
117
118
119void NetworkStream::connectSynchronizeable(Synchronizeable& sync)
120{
121  this->synchronizeables.push_back(&sync);
122
123  if( this->networkSockets.size()>0 )
124    this->bActive = true;
125}
126
127
128void NetworkStream::processData()
129{
130  //PRINTF(0)("processData()\n");
131  if ( this->type == NET_SERVER )
132    this->updateConnectionList();
133
134  for (HandshakeVector::iterator it = handshakes.begin(); it!=handshakes.end(); it++)
135  {
136    if ( *it )
137    {
138      if ( (*it)->completed() )
139      {
140        if ( (*it)->ok() )
141        {
142          NetworkManager::getInstance()->setHostID( (*it)->getHostId() );
143          myHostId = NetworkManager::getInstance()->getHostID();
144          delete *it;
145          *it = NULL;
146          PRINT(0)("handshake finished\n");
147        }
148        else
149        {
150          PRINT(1)("handshake failed!\n");
151          delete *it;
152          *it = NULL;
153          //TODO: handle error
154        }
155      }
156    }
157  }
158
159
160  /* DOWNSTREAM */
161
162  int dataLength;
163  int reciever;
164  Header header;
165  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
166  {
167    if ( (*it)->getOwner() == myHostId )
168    {
169      PRINTF(0)("sync: %s\n", (*it)->getName());
170      reciever = 0;
171      do {
172        dataLength = (*it)->readBytes(downBuffer, DATA_STREAM_BUFFER_SIZE, reciever);
173
174        if ( dataLength<=0 ){
175          reciever = 0;
176          continue;
177        }
178
179        PRINTF(0)("read %d bytes\n", dataLength);
180
181        dataLength = networkProtocol->createHeader((byte*)downBuffer, dataLength, DATA_STREAM_BUFFER_SIZE, static_cast<const Synchronizeable&>(*(*it)));
182
183        if ( dataLength<=0 )
184          continue;
185
186        if ( reciever!=0 )
187        {
188          if ( networkSockets[reciever] )
189          {
190            PRINTF(0)("write %d bytes to socket\n", dataLength);
191            networkSockets[reciever]->writePacket(downBuffer, dataLength);
192          }
193          else
194          {
195            PRINTF(1)("networkSockets[reciever] == NULL\n");
196          }
197        }
198        else
199        {
200          for ( int i = 1; i<networkSockets.size(); i++)
201          {
202            if ( networkSockets[i] )
203              networkSockets[i]->writePacket(downBuffer, dataLength);
204          }
205        }
206
207      } while( reciever!=0 );
208    }
209  }
210
211  /* UPSTREAM */
212
213  for ( int i = 1; i<networkSockets.size(); i++)
214  {
215    if ( networkSockets[i] )
216    {
217      do {
218        dataLength = networkSockets[i]->readPacket(upBuffer, DATA_STREAM_BUFFER_SIZE);
219
220        if ( dataLength<=0 )
221          continue;
222
223        PRINTF(0)("read %d bytes from socket\n", dataLength);
224        header = networkProtocol->extractHeader(upBuffer, dataLength);
225        dataLength -= sizeof(header);
226
227        if ( dataLength != header.length )
228        {
229          PRINTF(1)("packetsize in header and real packetsize do not match! %d:%d\n", dataLength, header.length);
230          continue;
231        }
232
233        for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
234        {
235          if ( *it && (*it)->getUniqueID()==header.uniqueID )
236            (*it)->writeBytes(upBuffer+sizeof(header), dataLength);
237        }
238
239      } while ( dataLength>0 );
240    }
241  }
242
243#if 0
244  int dataLength = 0;
245
246  /* DOWNSTREAM */
247  printf("\nSynchronizeable: %s\n", this->synchronizeables->getName());
248  PRINT(0)("============= DOWNSTREAM:===============\n");
249  /* first of all read the synchronizeable's data: */
250  if( this->isServer())
251    dataLength = this->synchronizeables->readBytes((byte*)downBuffer);
252
253  if( dataLength > 0)
254  {
255    /* send the received data to connectionMonitor */
256    this->connectionMonitor->processPacket((byte*)downBuffer, dataLength);
257
258    dataLength = this->networkProtocol->createHeader((byte*)downBuffer, dataLength, DATA_STREAM_BUFFER_SIZE,
259                 *(this->synchronizeables), 12/* some random number (no real id)*/);
260
261    /* pass the data to the network socket */
262 //   dataLength = this->networkSocket->writeBytes((byte*)downBuffer, dataLength);
263    /* check if there was an error */
264    if( dataLength == -1)
265    {
266      PRINTF(0)("Error in writing data to the NetworkSocket\n");
267    }
268  }
269
270
271  /* UPSTREAM */
272  dataLength = 0;
273  PRINT(0)("============== UPSTREAM:================\n");
274  /* first of all read the next Orxonox Network Header */
275
276  if( this->state == NET_REC_HEADER)
277  {
278//    dataLength = this->networkSocket->readBlock((byte*)upBuffer, sizeof(Header));
279    if( dataLength == sizeof(Header))
280    {
281      this->packetHeader = this->networkProtocol->extractHeader((byte*) upBuffer , dataLength);
282      printf("NetworkStream::processData() - Got Header: Protocol %u, Version: %u, Sender: %u, Receiver: %u, Length: %u\n",
283             this->packetHeader.protocol, this->packetHeader.version, this->packetHeader.senderID,
284             this->packetHeader.receiverID, this->packetHeader.length);
285      /* FIXME: what if it was no this->packetHeader? catch? eg: the protocol identifier, receiver id*/
286
287      this->state = NET_REC_DATA;
288    }
289  }
290  if( this->state == NET_REC_DATA)
291  {
292    /* now read the data */
293//    dataLength = this->networkSocket->readBlock((byte*)upBuffer, this->packetHeader.length);
294    /* check if the data is available and process it if so */
295    if( dataLength == this->packetHeader.length)
296    {
297      printf("NetworkStream::processData() - Got Data: %i bytes\n", dataLength);
298      /* send the received data to connectionMonitor */
299      this->connectionMonitor->processPacket((byte*)upBuffer, this->packetHeader.length);
300      /* now pass the data to the sync object */
301      if( !this->isServer())
302        this->synchronizeables->writeBytes((byte*)upBuffer, this->packetHeader.length);
303
304      this->state = NET_REC_HEADER;
305    }
306  }
307
308#endif
309}
310
311void NetworkStream::updateConnectionList( )
312{
313  //check for new connections
314
315  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
316
317  if ( tempNetworkSocket )
318  {
319    int clientId;
320    if ( freeSocketSlots.size() >0 )
321    {
322      clientId = freeSocketSlots.back();
323      freeSocketSlots.pop_back();
324      networkSockets[clientId] = tempNetworkSocket;
325      handshakes[clientId] = new Handshake(true, clientId);
326    } else
327    {
328      clientId = networkSockets.size();
329      networkSockets.push_back(tempNetworkSocket);
330      handshakes.push_back(new Handshake(true, clientId));
331    }
332
333    PRINTF(0)("New Client: %d\n", clientId);
334
335    this->connectSynchronizeable(*handshakes[clientId]);
336  }
337
338
339  //check if connections are ok else remove them
340  for ( int i = 1; i<networkSockets.size(); i++)
341  {
342    if ( networkSockets[i] && !networkSockets[i]->isOk() )
343    {
344      //TODO: tell EntityManager that this player left the game
345      PRINTF(0)("Client is gone: %d\n", i);
346
347      //delete networkSockets[i];
348      networkSockets[i]->disconnectServer();
349      networkSockets[i]->destroy();
350      networkSockets[i] = NULL;
351      delete handshakes[i];
352      handshakes[i] = NULL;
353
354      if ( i == networkSockets.size()-1 )
355      {
356        networkSockets.pop_back();
357        handshakes.pop_back();
358      }
359      else
360      {
361        freeSocketSlots.push_back(i);
362      }
363    }
364  }
365
366
367}
368
369
Note: See TracBrowser for help on using the repository browser.