Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6061 was 6060, checked in by bwuest, 18 years ago

Network changes

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