- Timestamp:
- Jul 11, 2006, 7:50:12 PM (18 years ago)
- Location:
- trunk/src/lib/network
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/network/netdefs.h
r8802 r9246 25 25 26 26 27 //!< enum indicating the type of the node 27 28 typedef enum { 28 29 NET_SERVER, … … 30 31 } NodeType; 31 32 33 //!< enum indicating the type of the network connection (2 protocols supported) 32 34 typedef enum ConnectionType { 33 35 NET_UDP = 0, … … 35 37 }; 36 38 37 39 //!< the type of the user id (special number never used elsewhere) 38 40 typedef enum { 39 41 NET_UID_UNASSIGNED = -1, -
trunk/src/lib/network/network_stream.cc
r9235 r9246 10 10 11 11 ### File Specific: 12 main-programmer: claudio13 co-programmer: 12 main-programmer: Christoph Renner rennerc@ee.ethz.ch 13 co-programmer: Patrick Boenzli boenzlip@orxonox.ethz.ch 14 14 */ 15 15 16 16 17 /* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module18 For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput19 */20 17 #define DEBUG_MODULE_NETWORK 21 18 … … 64 61 65 62 63 /** 64 * connect to a server as a client 65 * @param host: host name (address) 66 * @param port: port number 67 */ 66 68 NetworkStream::NetworkStream( std::string host, int port ) 67 69 { … … 75 77 76 78 79 /** 80 * start as a server 81 * @param port: at this port 82 */ 77 83 NetworkStream::NetworkStream( int port ) 78 84 { … … 84 90 85 91 92 /** 93 * generic init functions 94 */ 86 95 void NetworkStream::init() 87 96 { … … 93 102 myHostId = 0; 94 103 currentState = 0; 95 104 96 105 remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 ); 97 106 98 107 assert( Zip::getInstance()->loadDictionary( "testdict" ) >= 0 ); 99 108 this->dictClient = Zip::getInstance()->loadDictionary( "dict2pl_client" ); … … 104 113 105 114 115 /** 116 * deconstructor 117 */ 106 118 NetworkStream::~NetworkStream() 107 119 { … … 120 132 i->second.socket = NULL; 121 133 } 122 134 123 135 if ( i->second.handshake ) 124 136 { … … 126 138 i->second.handshake = NULL; 127 139 } 128 140 129 141 if ( i->second.connectionMonitor ) 130 142 { … … 138 150 139 151 152 /** 153 * creates a new instance of the network game manager 154 */ 140 155 void NetworkStream::createNetworkGameManager() 141 156 { … … 148 163 149 164 165 /** 166 * starts the network handshake 167 */ 150 168 void NetworkStream::startHandshake() 151 169 { … … 154 172 assert( peers[0].handshake == NULL ); 155 173 peers[0].handshake = hs; 156 174 157 175 hs->setPreferedNickName( Preferences::getInstance()->getString( "multiplayer", "nickname", "Player" ) ); 158 176 159 177 // peers[0].handshake->setSynchronized( true ); 160 178 //this->connectSynchronizeable(*hs); … … 164 182 165 183 184 /** 185 * this functions connects a synchronizeable to the networkstream, therefore synchronizeing 186 * it all over the network and creating it on the other platforms (if and only if it is a 187 * server 188 */ 166 189 void NetworkStream::connectSynchronizeable(Synchronizeable& sync) 167 190 { … … 173 196 174 197 198 /** 199 * removes the synchronizeable from the list of synchronized entities 200 */ 175 201 void NetworkStream::disconnectSynchronizeable(Synchronizeable& sync) 176 202 { … … 179 205 if (disconnectSynchro != this->synchronizeables.end()) 180 206 this->synchronizeables.erase(disconnectSynchro); 181 207 182 208 oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks(); 183 209 } 184 210 185 211 212 /** 213 * this is called to process data from the network socket to the synchronizeable and vice versa 214 */ 186 215 void NetworkStream::processData() 187 216 { 188 217 int tick = SDL_GetTicks(); 189 218 190 219 currentState++; 191 220 192 221 if ( this->type == NET_SERVER ) 193 222 { 194 223 if ( serverSocket ) 195 224 serverSocket->update(); 196 225 197 226 this->updateConnectionList(); 198 227 } 199 228 else 200 229 { 230 // check if the connection is ok else terminate and remove 201 231 if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) ) 202 232 { … … 210 240 delete peers[0].handshake; 211 241 peers[0].handshake = NULL; 212 242 213 243 if ( peers[0].connectionMonitor ) 214 244 delete peers[0].connectionMonitor; … … 219 249 cleanUpOldSyncList(); 220 250 handleHandshakes(); 221 251 222 252 // order of up/downstream is important!!!! 223 253 // don't change it 224 254 handleDownstream( tick ); 225 255 handleUpstream( tick ); 226 227 } 228 256 } 257 258 259 /** 260 * if we are a server update the connection list to accept new connections (clients) 261 * also start the handsake for the new clients 262 */ 229 263 void NetworkStream::updateConnectionList( ) 230 264 { … … 233 267 NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket(); 234 268 269 // we got new network node 235 270 if ( tempNetworkSocket ) 236 271 { 237 272 int clientId; 238 if ( freeSocketSlots.size() >0 ) 273 // if there is a list of free client id slots, take these 274 if ( freeSocketSlots.size() > 0 ) 239 275 { 240 276 clientId = freeSocketSlots.back(); … … 246 282 peers[clientId].userId = clientId; 247 283 peers[clientId].isServer = false; 248 } else 284 } 285 else 249 286 { 250 287 clientId = 1; 251 288 252 289 for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ ) 253 290 if ( it->first >= clientId ) 254 291 clientId = it->first + 1; 255 292 256 293 peers[clientId].socket = tempNetworkSocket; 257 294 peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID()); … … 260 297 peers[clientId].userId = clientId; 261 298 peers[clientId].isServer = false; 262 299 263 300 PRINTF(0)("num sync: %d\n", synchronizeables.size()); 264 301 } 265 302 303 // check if there are too many clients connected 266 304 if ( clientId > MAX_CONNECTIONS ) 267 305 { … … 270 308 } 271 309 else 272 273 PRINTF(0)("New Client: %d\n", clientId); 310 { 311 PRINTF(0)("New Client: %d\n", clientId); 312 } 274 313 275 314 //this->connectSynchronizeable(*handshakes[clientId]); 276 315 } 316 317 277 318 278 319 //check if connections are ok else remove them 279 320 for ( PeerList::iterator it = peers.begin(); it != peers.end(); ) 280 321 { 281 if ( 322 if ( 282 323 it->second.socket && 283 ( 324 ( 284 325 !it->second.socket->isOk() || 285 326 it->second.connectionMonitor->hasTimedOut() … … 291 332 reason = "timeout"; 292 333 PRINTF(0)("Client is gone: %d (%s)\n", it->second.userId, reason.c_str()); 293 294 //assert(false); 295 334 335 336 // clean up the network data 296 337 it->second.socket->disconnectServer(); 297 338 delete it->second.socket; … … 301 342 delete it->second.connectionMonitor; 302 343 it->second.connectionMonitor = NULL; 303 344 304 345 if ( it->second.handshake ) 305 346 delete it->second.handshake; 306 347 it->second.handshake = NULL; 307 348 308 349 for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ ) 309 350 { … … 314 355 315 356 freeSocketSlots.push_back( it->second.userId ); 316 357 317 358 PeerList::iterator delit = it; 318 359 it++; 319 360 320 361 peers.erase( delit ); 321 362 322 363 continue; 323 364 } 324 365 325 366 it++; 326 367 } … … 328 369 329 370 } 371 330 372 331 373 void NetworkStream::debug() … … 348 390 349 391 392 /** 393 * @returns the number of synchronizeables registered to this stream 394 */ 350 395 int NetworkStream::getSyncCount() 351 396 { … … 359 404 } 360 405 361 /** 362 * check if handshakes completed 406 407 /** 408 * check if handshakes completed. if so create the network game manager else remove it again 363 409 */ 364 410 void NetworkStream::handleHandshakes( ) … … 383 429 MessageManager::getInstance()->setUniqueID( it->second.handshake->getMessageManagerId() ); 384 430 } 385 431 386 432 387 433 PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId()); … … 396 442 { 397 443 handleNewClient( it->second.userId ); 398 444 399 445 if ( PlayerStats::getStats( it->second.userId ) && it->second.handshake->getPreferedNickName() != "" ) 400 446 { … … 402 448 } 403 449 } 404 450 405 451 PRINT(0)("handshake finished delete it\n"); 406 452 delete it->second.handshake; … … 420 466 } 421 467 468 422 469 /** 423 470 * handle upstream network traffic … … 427 474 int offset; 428 475 int n; 429 476 430 477 for ( PeerList::reverse_iterator peer = peers.rbegin(); peer != peers.rend(); peer++ ) 431 478 { 432 offset = INTSIZE; //make already space for length 433 479 offset = INTSIZE; // reserve enough space for the packet length 480 481 // continue with the next peer if this peer has no socket assigned (therefore no network) 434 482 if ( !peer->second.socket ) 435 483 continue; 436 484 485 // header informations: current state 437 486 n = Converter::intToByteArray( currentState, buf + offset, UDP_PACKET_SIZE - offset ); 438 487 assert( n == INTSIZE ); 439 488 offset += n; 440 489 490 // header informations: last acked state 441 491 n = Converter::intToByteArray( peer->second.lastAckedState, buf + offset, UDP_PACKET_SIZE - offset ); 442 492 assert( n == INTSIZE ); 443 493 offset += n; 444 494 495 // header informations: last recved state 445 496 n = Converter::intToByteArray( peer->second.lastRecvedState, buf + offset, UDP_PACKET_SIZE - offset ); 446 497 assert( n == INTSIZE ); 447 498 offset += n; 448 499 500 // now write all synchronizeables in the packet 449 501 for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ ) 450 502 { 451 503 int oldOffset = offset; 452 504 Synchronizeable & sync = **it; 453 505 506 // do not include synchronizeables with uninit id and syncs that don't want to be synchronized 454 507 if ( !sync.beSynchronized() || sync.getUniqueID() < 0 ) 455 508 continue; 456 509 457 // if handshake not finished only sync handshake510 // if handshake not finished only sync handshake 458 511 if ( peer->second.handshake && sync.getLeafClassID() != CL_HANDSHAKE ) 459 512 continue; 460 513 514 // if we are a server and this is not our handshake 461 515 if ( isServer() && sync.getLeafClassID() == CL_HANDSHAKE && sync.getUniqueID() != peer->second.userId ) 462 516 continue; 463 464 //do not sync null parent 517 518 /* list of synchronizeables that will never be synchronized over the network: */ 519 // do not sync null parent 465 520 if ( sync.getLeafClassID() == CL_NULL_PARENT ) 466 521 continue; 467 522 468 523 assert( offset + INTSIZE <= UDP_PACKET_SIZE ); 469 470 // server fakes uniqueid=0 for handshake524 525 // server fakes uniqueid == 0 for handshake 471 526 if ( this->isServer() && sync.getUniqueID() < MAX_CONNECTIONS - 1 ) 472 527 n = Converter::intToByteArray( 0, buf + offset, UDP_PACKET_SIZE - offset ); 473 528 else 474 529 n = Converter::intToByteArray( sync.getUniqueID(), buf + offset, UDP_PACKET_SIZE - offset ); 530 475 531 assert( n == INTSIZE ); 476 532 offset += n; 477 478 // make space for size533 534 // make space for size 479 535 offset += INTSIZE; 480 536 481 537 n = sync.getStateDiff( peer->second.userId, buf + offset, UDP_PACKET_SIZE-offset, currentState, peer->second.lastAckedState, -1000 ); 482 538 offset += n; 483 //NETPRINTF(0)("GGGGGEEEEETTTTT: %s (%d) %d\n",sync.getClassName(), sync.getUniqueID(), n); 484 539 485 540 assert( Converter::intToByteArray( n, buf + offset - n - INTSIZE, INTSIZE ) == INTSIZE ); 486 487 // check if all bytes == 0 -> remove data488 // TODO not all synchronizeables like this maybe add Synchronizeable::canRemoveZeroDiff()489 bool allZero = true; 490 for ( int i = 0; i < n; i++ ) 491 { 492 if ( buf[i+oldOffset+2*INTSIZE] != 0 ) 493 allZero = false; 494 } 495 496 if ( allZero )497 {498 //NETPRINTF(n)("REMOVE ZERO DIFF: %s (%d)\n", sync.getClassName(), sync.getUniqueID());499 offset = oldOffset; 500 } 501 502 503 } 504 541 542 // check if all data bytes == 0 -> remove data and the synchronizeable from the sync process since there is no update 543 // TODO not all synchronizeables like this maybe add Synchronizeable::canRemoveZeroDiff() 544 bool allZero = true; 545 for ( int i = 0; i < n; i++ ) 546 { 547 if ( buf[i+oldOffset+2*INTSIZE] != 0 ) 548 allZero = false; 549 } 550 // if there is no new data in this synchronizeable reset the data offset to the last state -> dont synchronizes 551 // data that hast not changed 552 if ( allZero ) 553 { 554 offset = oldOffset; 555 } 556 } // all synchronizeables written 557 558 559 505 560 for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ ) 506 561 { 507 562 Synchronizeable & sync = **it; 508 563 509 564 if ( !sync.beSynchronized() || sync.getUniqueID() < 0 ) 510 565 continue; 511 566 512 567 sync.handleSentState( peer->second.userId, currentState, peer->second.lastAckedState ); 513 568 } 514 569 570 515 571 assert( Converter::intToByteArray( offset, buf, INTSIZE ) == INTSIZE ); 516 572 573 // now compress the data with the zip library 517 574 int compLength = 0; 518 575 if ( this->isServer() ) … … 520 577 else 521 578 compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictClient ); 522 579 523 580 if ( compLength <= 0 ) 524 581 { … … 526 583 continue; 527 584 } 528 585 529 586 assert( peer->second.socket->writePacket( compBuf, compLength ) ); 530 587 531 588 if ( this->remainingBytesToWriteToDict > 0 ) 532 589 writeToNewDict( buf, offset, true ); 533 590 534 591 peer->second.connectionMonitor->processUnzippedOutgoingPacket( tick, buf, offset, currentState ); 535 592 peer->second.connectionMonitor->processZippedOutgoingPacket( tick, compBuf, compLength, currentState ); 536 537 //NETPRINTF(n)("send packet: %d userId = %d\n", offset, peer->second.userId); 593 538 594 } 539 595 } … … 545 601 { 546 602 int offset = 0; 547 603 548 604 int length = 0; 549 605 int packetLength = 0; … … 554 610 int fromState = 0; 555 611 int syncDataLength = 0; 556 612 557 613 for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ ) 558 614 { 559 615 560 616 if ( !peer->second.socket ) 561 617 continue; … … 564 620 { 565 621 peer->second.connectionMonitor->processZippedIncomingPacket( tick, compBuf, compLength ); 566 567 //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength); 622 568 623 packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE ); 569 624 … … 574 629 continue; 575 630 } 576 631 577 632 if ( this->remainingBytesToWriteToDict > 0 ) 578 633 writeToNewDict( buf, packetLength, false ); 579 634 580 635 assert( Converter::byteArrayToInt( buf, &length ) == INTSIZE ); 581 636 assert( Converter::byteArrayToInt( buf + INTSIZE, &state ) == INTSIZE ); … … 584 639 //NETPRINTF(n)("ackedstate: %d\n", ackedState); 585 640 offset = 4*INTSIZE; 586 641 587 642 peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, packetLength, state, ackedState ); 588 643 589 644 //NETPRINTF(n)("got packet: %d, %d\n", length, packetLength); 590 645 591 646 //if this is an old state drop it 592 647 if ( state <= peer->second.lastRecvedState ) 593 648 continue; 594 649 595 650 if ( packetLength != length ) 596 651 { … … 599 654 continue; 600 655 } 601 656 602 657 while ( offset + 2*INTSIZE < length ) 603 658 { … … 605 660 assert( Converter::byteArrayToInt( buf + offset, &uniqueId ) == INTSIZE ); 606 661 offset += INTSIZE; 607 662 608 663 assert( Converter::byteArrayToInt( buf + offset, &syncDataLength ) == INTSIZE ); 609 664 offset += INTSIZE; 610 665 611 666 assert( syncDataLength > 0 ); 612 667 assert( syncDataLength < 10000 ); 613 668 614 669 Synchronizeable * sync = NULL; 615 670 616 671 for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ ) 617 { 672 { 618 673 // client thinks his handshake has id 0!!!!! 619 674 if ( (*it)->getUniqueID() == uniqueId || ( uniqueId == 0 && (*it)->getUniqueID() == peer->second.userId ) ) … … 623 678 } 624 679 } 625 680 626 681 if ( sync == NULL ) 627 682 { … … 632 687 continue; 633 688 } 634 689 635 690 if ( !peers[peer->second.userId].isServer ) 636 691 { … … 638 693 continue; 639 694 } 640 695 641 696 int leafClassId; 642 697 if ( INTSIZE > length - offset ) … … 647 702 648 703 Converter::byteArrayToInt( buf + offset, &leafClassId ); 649 704 650 705 assert( leafClassId != 0 ); 651 706 652 707 BaseObject * b = NULL; 653 708 /* These are some small exeptions in creation: Not all objects can/should be created via Factory */ … … 674 729 sync->setUniqueID( uniqueId ); 675 730 sync->setSynchronized(true); 676 731 677 732 PRINTF(0)("Fabricated %s with id %d\n", sync->getClassName(), sync->getUniqueID()); 678 733 } … … 685 740 } 686 741 } 687 688 689 int n = sync->setStateDiff( peer->second.userId, buf+offset, syncDataLength, state, fromState ); 742 743 744 int n = sync->setStateDiff( peer->second.userId, buf+offset, syncDataLength, state, fromState ); 690 745 offset += n; 691 746 //NETPRINTF(0)("SSSSSEEEEETTTTT: %s %d\n",sync->getClassName(), n); 692 747 693 748 } 694 749 695 750 if ( offset != length ) 696 751 { … … 698 753 peer->second.socket->disconnectServer(); 699 754 } 700 701 755 756 702 757 for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ ) 703 758 { 704 759 Synchronizeable & sync = **it; 705 760 706 761 if ( !sync.beSynchronized() || sync.getUniqueID() < 0 ) 707 762 continue; 708 763 709 764 sync.handleRecvState( peer->second.userId, state, fromState ); 710 765 } 711 766 712 767 assert( peer->second.lastAckedState <= ackedState ); 713 768 peer->second.lastAckedState = ackedState; 714 769 715 770 assert( peer->second.lastRecvedState < state ); 716 771 peer->second.lastRecvedState = state; 717 772 718 773 } 719 720 } 721 774 775 } 776 722 777 } 723 778 … … 729 784 { 730 785 MessageManager::getInstance()->initUser( userId ); 731 786 732 787 networkGameManager->signalNewPlayer( userId ); 733 788 } … … 739 794 { 740 795 int now = SDL_GetTicks(); 741 796 742 797 for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end(); ) 743 798 { … … 762 817 if ( remainingBytesToWriteToDict <= 0 ) 763 818 return; 764 819 765 820 if ( length > remainingBytesToWriteToDict ) 766 821 length = remainingBytesToWriteToDict; 767 822 768 823 std::string fileName = ResourceManager::getInstance()->getDataDir(); 769 824 fileName += "/dicts/newdict"; 770 825 771 826 if ( upstream ) 772 827 fileName += "_upstream"; 773 828 else 774 829 fileName += "_downstream"; 775 830 776 831 FILE * f = fopen( fileName.c_str(), "a" ); 777 832 778 833 if ( !f ) 779 834 { … … 782 837 return; 783 838 } 784 839 785 840 if ( fwrite( data, 1, length, f ) != length ) 786 841 { … … 789 844 return; 790 845 } 791 846 792 847 fclose( f ); 793 794 remainingBytesToWriteToDict -= length; 795 } 796 797 798 799 800 801 848 849 remainingBytesToWriteToDict -= length; 850 } 851 852 853 854 855 856 -
trunk/src/lib/network/network_stream.h
r8623 r9246 22 22 class NetworkGameManager; 23 23 24 //!< this structure contains informations about the network node 24 25 class PeerInfo 25 26 { … … 27 28 PeerInfo() { clear(); } 28 29 void clear() { userId = 0; isServer = false; socket = NULL; handshake = NULL; lastAckedState = 0; lastRecvedState = 0; connectionMonitor = NULL; } 30 31 32 public: 29 33 int userId; 30 34 bool isServer; … … 72 76 73 77 void debug(); 74 78 75 79 inline PeerInfo & getPeerInfo( int userId ) { return peers[userId]; } 76 80 … … 80 84 void handleHandshakes(); 81 85 void handleUpstream( int tick ); 82 void handleDownstream(int tick ); 86 void handleDownstream(int tick ); 83 87 void handleNewClient( int userId ); 84 88 void cleanUpOldSyncList(); 85 89 86 90 void writeToNewDict( byte * data, int length, bool upstream ); 87 91 … … 96 100 97 101 int myHostId; 98 102 99 103 int currentState; //!< current state id 100 104 … … 102 106 103 107 std::map<int,int> oldSynchronizeables; //!< used to save recently deleted sync ids to not recreate them 104 108 105 109 byte buf[UDP_PACKET_SIZE]; //!< used by handleUp/Downstream 106 110 byte compBuf[UDP_PACKET_SIZE]; //!< used by handleUp/Downstream -
trunk/src/lib/network/udp_server_socket.h
r8802 r9246 47 47 public: 48 48 UdpServerSocket( int port); 49 50 49 virtual ~UdpServerSocket(); 51 50 52 51 virtual bool listen( unsigned int port ); 53 52 54 53 virtual NetworkSocket* getNewSocket( void ); 55 54 56 55 virtual void close(); 57 56 58 57 virtual void update(); 59 58 60 59 void removeUserPackets( int userId ); 61 60 void removeUser( int userId ); … … 64 63 int getPacketCount( int childId ); 65 64 void initUser( int childId, IPaddress ip, byte randomByte ); 66 65 67 66 private: 68 67 UDPsocket socket; //!< will be uses to send/recieve data
Note: See TracChangeset
for help on using the changeset viewer.