Esempio n. 1
0
int main( int argc, char** argv ) {

	wawo::app::App application ;

	wawo::net::SocketAddr remote_addr( "192.168.2.7", 12121 );
	WAWO_REF_PTR<wawo::net::Socket> socket ( new wawo::net::Socket( remote_addr,wawo::net::F_AF_INET , wawo::net::ST_STREAM, wawo::net::P_TCP ) );
	int rt = socket->Open();
	WAWO_RETURN_V_IF_NOT_MATCH(rt, rt == wawo::OK);
	rt = socket->Connect();
	WAWO_RETURN_V_IF_NOT_MATCH(rt, rt == wawo::OK);

	WWRP<wawo::net::core::TLP_Abstract> tlp(new typename PeerT::TLPT());
	socket->SetTLP(tlp);
	rt = socket->TLP_Handshake();
	WAWO_RETURN_V_IF_NOT_MATCH(rt, rt == wawo::OK);

	WAWO_REF_PTR<PeerT> peer(new PeerT());
	peer->AttachSocket(socket);

	int sndhellort;
	PEER_SND_HELLO(peer, sndhellort);
	WAWO_ASSERT(sndhellort==wawo::OK);

	int ec;
	do {
		WWSP<MessageT> arrives[5];
		wawo::u32_t count = peer->DoReceiveMessages(arrives, 5, ec);

		WAWO_ASSERT(count == 1);
		WAWO_ASSERT(ec == wawo::OK);
		WAWO_ASSERT(arrives[0]->GetType() == wawo::net::peer::message::Wawo::T_RESPONSE );

		wawo::Len_CStr reqstr("this is request from client");
		WWSP<wawo::algorithm::Packet> reqpack( new wawo::algorithm::Packet() );

		reqpack->Write<wawo::u32_t>(services::C_ECHO_STRING_REQUEST_TEST);
		reqpack->Write<wawo::u32_t>(reqstr.Len());
		reqpack->Write((wawo::byte_t*)reqstr.CStr(),reqstr.Len());

		reqpack->WriteLeft < wawo::net::ServiceIdT >(services::S_ECHO);
		WWSP< MessageT> message_to_req(new MessageT(reqpack));
		int sndrt = peer->Request(message_to_req);
		WAWO_ASSERT(sndrt == wawo::OK);
	} while (ec == wawo::OK);

	WAWO_LOG_WARN( "main", "socket server exit ..." ) ;
	return wawo::OK;
}
MC2BoundingBox getBBoxForMap( uint32 mapID, uint32 listenPort ) {
   DatagramReceiver 
      receiver( MultiCastProperties::changeMapSetPort( listenPort ),
                DatagramReceiver::FINDFREEPORT );
   uint32 mapip = MultiCastProperties::getNumericIP( MODULE_TYPE_MAP, true );
   uint16 mapport = MultiCastProperties::getPort( MODULE_TYPE_MAP, true );
   uint32 mapSet = Properties::getMapSet();
   
   if ( mapSet != MAX_UINT32 ) {
      // code also exists in PacketContainer.cpp and
      // ModuleMap.cpp, move to utility function?
      IPnPort before( mapip, mapport );
      IPnPort newaddr = MultiCastProperties::
         changeMapSetAddr( IPnPort( mapip, mapport ) );

      mapip = newaddr.getIP();
      mapport = newaddr.getPort();
      mc2dbg << "[getBBoxForMap] Changed map module addr from "
             << before << " -> " << newaddr
             << " because mapSet = " << mapSet;
   }

   Packet _pack( MAX_PACKET_SIZE ); // For receiving the mapreply
   DatagramSender sock;


   const int waittime = 1000000;
   uint32 status = StringTable::NOT;
   const int maxRetries = 5;
   int nbrRetries = 0;
   while ( status != StringTable::OK && nbrRetries++ <= maxRetries ) {      
      AllMapRequestPacket reqpack( Packet::RequestID( 1 ),
                                   Packet::PacketID( 1 ),
                                   AllMapRequestPacket::BOUNDINGBOX );
      
      reqpack.setOriginIP( NetUtility::getLocalIP() );
      reqpack.setOriginPort( receiver.getPort() );
      reqpack.setResendNbr((byte) nbrRetries-1);
      
      // Send request to open TCP connection between local and mapmodule
      
      if ( ! sock.send( &reqpack, mapip, mapport ) ) {
         mc2log << error << "[getBBoxForMap] could not send "
                << " AllMapRequestPacket - retrying." << endl;
         continue; // Go another round in the loop.
      }
      
      // Receive packet with ip and port to a mapModule
      if ( ! receiver.receive( &_pack, waittime ) ) {
         mc2log << error << "[getBBoxForMap] error receiving ack - retrying."
                << endl;
         continue; // Go another round in the loop.
      }
      
      if ( _pack.getSubType() != Packet::PACKETTYPE_ALLMAPREPLY ) {
         mc2log << error << "[getBBoxForMap] Got packet with subtype "
                << _pack.getSubTypeAsString()
                << " when expecting allmapreply." << endl;
         continue; // Please try again.
      }
      
      AllMapReplyPacket* pack = static_cast<AllMapReplyPacket *>( &_pack );
      
      status = pack->getStatusCode();
      

      uint32 myMap = 0;
      while ( myMap < pack->getNbrMaps() &&
              mapID != pack->getMapID( myMap ) ){
         ++myMap;
      }

      if ( myMap != pack->getNbrMaps() ) {

         mc2dbg << "[getBBoxForMap] map "
                << prettyMapID(mapID) << " index " << myMap
                << " found " << prettyMapID( pack->getMapID( myMap ) ) << endl;
         MC2BoundingBox bbox;
         pack->setMC2BoundingBox( myMap, &bbox );

         return bbox;

      } else {
         mc2log << warn << "[getBBoxForMap] Map " << prettyMapID( mapID ) 
                << " not found in AllMapReplyPacket." << endl;
      }
   }

   return MC2BoundingBox();
}
TCPSocket*
ModuleMap::getMapLoadingSocket( uint32 mapID,
                                uint32 loadMapRequestType,
                                const char* handshake,
                                byte zoomlevel,
                                MapSafeVector* loadedMaps,
                                uint32* mapVersion,
                                uint32* generatorVersion )
{
   uint32 mapVersionToUse = MAX_UINT32;
   uint32 generatorVersionToUse = MAX_UINT32;
   if ( mapVersion != NULL && generatorVersion != NULL ) {
      // Set the versions to use to the ones sent in
      mapVersionToUse = *mapVersion;
      generatorVersionToUse = *generatorVersion;
      // Set the ones sent in to MAX_UINT32 to detect errors
      *mapVersion = MAX_UINT32;
      *generatorVersion = MAX_UINT32;
   }
   
   DatagramReceiver receiver(8000, DatagramReceiver::FINDFREEPORT);
   
   mc2dbg4 << here << " localport " << receiver.getPort() << endl;

   uint32 mapip = MultiCastProperties::getNumericIP( MODULE_TYPE_MAP, true );
   uint16 mapport = MultiCastProperties::getPort( MODULE_TYPE_MAP, true );

   // check map set
   uint32 mapSet = Properties::getMapSet();
   if (mapSet != MAX_UINT32) {
      // code also exists in PacketContainer.cpp, move to utility function?
      mc2dbg4 << "[ModuleMap] going to change IP and port due to mapSet being set. "
                "mapSet: " << mapSet << ", IP before: " << prettyPrintIP(mapip)
             << ", port before: " << mapport << endl;
      mapip = mapip + (mapSet << 8);
      mapport = mapport | (mapSet << 13);
      mc2dbg4 << "[ModuleMap] changed IP and port. IP now: " << prettyPrintIP(mapip)
             << ", port now: " << mapport << endl;
   }
   
   uint32 status = StringTable::NOT;
   int maxRetries = 10;
   int nbrRetries = 0;

   Packet _pack(65536); // For receiving the mapreply
   DatagramSender sock;

   const int originalwaittime    =  2500000; // Wait 2.5 seconds.
   const int mapnotfoundwaittime =  2500000; // Wait 2.5 seconds.
   int waittime = originalwaittime;

   TCPSocket* TCPsock = NULL;
   
   while ( status != StringTable::OK && nbrRetries++ <= maxRetries ) {
      if ( nbrRetries > 1 ) {
         mc2log << info << here << " Retrying " << nbrRetries - 1 
                << " of " << maxRetries << endl;
      }
      if(loadedMaps != NULL)
         loadedMaps->jobThreadIsAlive(); // reset Jthread timeout clock.
      MapRequestPacket reqpack( uint16(1),  // reqID
                                uint16(1),  // PacketID
                                byte(loadMapRequestType), // Type of module
                                mapID,      // mapID
                                zoomlevel,  // Well, zoomlevel.
                                mapVersionToUse,
                                generatorVersionToUse
                                ); 
      reqpack.setOriginIP( NetUtility::getLocalIP() );
      reqpack.setOriginPort( receiver.getPort() );
      reqpack.setResendNbr((byte) nbrRetries-1);
      
      // Send request to open TCP connection between local and mapmodule
      
      if (!(sock.send(&reqpack, mapip, mapport))) {
         mc2log << error << here << " could not send - retrying"
                << endl;
         continue; // Go another round in the loop.
      }
      mc2dbg4 << "After send!" << endl;
      
      // Receive packet with ip and port to a mapModule
      if (!(receiver.receive(&_pack, waittime))) {
         mc2log << error << here << " error receiving ack - retrying"
                << endl;
         waittime = originalwaittime;
         continue; // Go another round in the loop.
      }

      bool timeout = false;
      while ( _pack.getSubType() == Packet::PACKETTYPE_ACKNOWLEDGE &&
              ! timeout ) {
         AcknowledgeRequestReplyPacket* ackPack =
            static_cast<AcknowledgeRequestReplyPacket*>(&_pack);
         uint32 packtime =
            ((AcknowledgeRequestReplyPacket*)&_pack)->getETA() * 1000;
         mc2log << info << "Got ack with " << packtime << " us delay" << endl;
         if ( ackPack->getStatus() != StringTable::OK ) {
            return NULL;
         }
         timeout = !receiver.receive(&_pack, packtime);         
      }

      if ( timeout ) {
         mc2log << error << "Got timeout after receiving ack-pack" << endl;
         continue; // Go around again
      }

      if ( _pack.getSubType() != Packet::PACKETTYPE_MAPREPLY ) {
         mc2log << error << "Got packet with subtype "
                << _pack.getSubTypeAsString()
                << " when expecting loadmapreply" << endl;
         continue; // Please try again.
      }
      
      MapReplyPacket* pack = (MapReplyPacket *)&_pack;
      
      status = pack->getStatus();
      
      if ( status != StringTable::OK || pack->getMapID() != mapID ) {
         mc2log << warn << "Got status \""
                << StringTable::getString(
                   StringTable::stringCode(pack->getStatus()),
                   StringTable::ENGLISH)
                << "\"-retrying. Wanted map = "
                << mapID
                << ", got reply for map = " << pack->getMapID() << endl;
         if ( status == StringTable::MAPNOTFOUND ) {
            // Wait longer if map not found ( loading? )
            waittime = mapnotfoundwaittime; 
         }
         if ( mapID != pack->getMapID() ) {
            status = StringTable::NOT; // Keep the loop running.
         }
         continue; // Go another round in the loop.
      }

      if ( mapVersion != NULL && generatorVersion != NULL ) {
         // Set the versions so that we know what we are caching.
         mc2dbg8 << "[ModuleMap]: Version from packet "
                 << hex << pack->getMapVersion() << ":"
                 << pack->getGeneratorVersion() << dec << endl;
         *mapVersion       = pack->getMapVersion();
         *generatorVersion = pack->getGeneratorVersion();

         // Check if new map is needed.
         if ( ! pack->newMapNeeded(mapVersionToUse,
                                   generatorVersionToUse) ) {
            // Same version. Use the cached map.
            return NULL;
         } 
      }
      
      TCPsock = new TCPSocket;      
      mc2dbg4 << here << " opening socket" << endl;
      TCPsock->open();
      
      uint32 ip = pack->getReplyIP();
      uint16 port = pack->getReplyPort();
      
      if ( ! TCPsock->connect(ip, port ) ) {
         mc2log << error << "Couldn't connect to " << ip
                << ":" << port << " - retrying" << endl;
         // Set status to not ok.
         status = StringTable::NOT;
         TCPsock->close();
         delete TCPsock;
         TCPsock = NULL;                  
         continue; // Please try again.
      }
      
      // Handshaking
      mc2dbg4 << "Starting handshake" << endl;
      int length = strlen(handshake) + 1;
      if ( TCPsock->writeAll( (byte*)handshake, length ) != length ) {
         mc2log << error << here << " handshake failed " << endl;
         status = StringTable::NOT;
         TCPsock->close();
         delete TCPsock;
         TCPsock = NULL;
         continue; // Please try again.
      } else {
         mc2dbg4 << "done" << endl;
      }
   }
   return TCPsock; // Should be NULL if we failed
}