示例#1
0
		void IPNDAgent::componentRun() throw ()
		{
			struct timeval tv;

			// every second we want to transmit a discovery message, timeout of 1 seconds
			tv.tv_sec = 1;
			tv.tv_usec = 0;

			// get the reference to the discovery agent
			dtn::net::DiscoveryAgent &agent = dtn::core::BundleCore::getInstance().getDiscoveryAgent();

			try {
				while (true)
				{
					ibrcommon::socketset fds;

					try {
						// select on all bound sockets
						_socket.select(&fds, NULL, NULL, &tv);

						// receive from all sockets
						for (ibrcommon::socketset::const_iterator iter = fds.begin(); iter != fds.end(); ++iter)
						{
							ibrcommon::multicastsocket &sock = dynamic_cast<ibrcommon::multicastsocket&>(**iter);

							char data[1500];
							ibrcommon::vaddress sender;
							DiscoveryBeacon beacon = agent.obtainBeacon();

							ssize_t len = sock.recvfrom(data, 1500, 0, sender);

							if (len < 0) return;

							stringstream ss;
							ss.write(data, len);

							try {
								ss >> beacon;

								if (beacon.isShort())
								{
									// generate name with the sender address
									beacon.setEID( dtn::data::EID("udp://[" + sender.address() + "]:4556") );

									// add generated tcpcl service if the services list is empty
									beacon.addService(dtn::net::DiscoveryService(dtn::core::Node::CONN_TCPIP, "ip=" + sender.address() + ";port=4556;"));
								}

								DiscoveryBeacon::service_list &services = beacon.getServices();

								// add source address if not set
								for (dtn::net::DiscoveryBeacon::service_list::iterator iter = services.begin(); iter != services.end(); ++iter) {
									DiscoveryService &service = (*iter);

									if ( (service.getParameters().find("port=") != std::string::npos) &&
											(service.getParameters().find("ip=") == std::string::npos) ) {

										// update service entry
										service.update("ip=" + sender.address() + ";" + service.getParameters());
									}
								}

								// announce the received beacon
								agent.onBeaconReceived(beacon);
							} catch (const dtn::InvalidDataException&) {
							} catch (const ibrcommon::IOException&) {
							}
						}

						// trigger an artificial timeout if the remaining timeout value is zero or below
						if ( tv.tv_sec <= 0 && tv.tv_usec <= 0 )
							throw ibrcommon::vsocket_timeout("timeout");

					} catch (const ibrcommon::vsocket_timeout&) {
						// reset timeout to 1 second
						tv.tv_sec = 1;
						tv.tv_usec = 0;
					}

					yield();
				}
			} catch (const ibrcommon::vsocket_interrupt&) {
				// vsocket has been interrupted - exit now
			} catch (const ibrcommon::socket_exception &ex) {
				// unexpected error - exit now
				IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "unexpected error: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
			}
		}