void InternalConnection::unsubscribe_range(channel_t lo, channel_t hi) { Datagram dg(CONTROL_REMOVE_RANGE); dg.add_channel(lo); dg.add_channel(hi); send_datagram(dg); }
/* \brief Just runs automatic tests Function sends a number of datagrams, spawns child thread or process and tries to receive at least one datagram. \retval 0 datagram was received \retval -1 datagram was not received */ int run_auto_test (const ACE_TCHAR *prog_name) { #if defined (ACE_HAS_PROCESS_SPAWN) ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in process mode\n"))); ACE_Process_Options opts; pid_t child_pid; opts.command_line (ACE_TEXT ("%s -p %d -t %d -a -r"), prog_name, dgram_port, dgram_recv_timeout.msec ()); if ((child_pid = ACE_Process_Manager::instance ()->spawn (opts)) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn_n()")), -1); #elif defined (ACE_HAS_THREADS) ACE_UNUSED_ARG (prog_name); ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in thread mode\n"))); if (ACE_Thread_Manager::instance ()->spawn (run_thread_receiver) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn_n ()")), -1); #else ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Cannot run in auto_test mode without fork or threads.\n")), -1); #endif /* defined (ACE_HAS_PROCESS_SPAWN) */ ACE_DEBUG ((LM_INFO, ACE_TEXT ("Sending datagrams on port %d in auto_test mode\n"), dgram_port)); ACE_SOCK_Dgram_Bcast socket; if (socket.open (ACE_Addr::sap_any) != -1) { // send datagrams until child finishes while (1) { send_datagram (socket, dgrams_no--); ACE_Time_Value child_timeout (1); #if defined (ACE_HAS_PROCESS_SPAWN) if (ACE_Process_Manager::instance ()->wait (child_pid, child_timeout, &receiver_exit_code) == child_pid) break; #else /* ACE_HAS_THREADS */ // sleep 1 second or wait for child thread child_timeout += ACE_OS::gettimeofday () ; if (ACE_Thread_Manager::instance ()->wait (&child_timeout) == 0) break; #endif } socket.close (); ACE_DEBUG ((LM_INFO, ACE_TEXT ("Child finished with %d exit code\n"), receiver_exit_code)); } else ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Cannot open broadcast socket")), -1); return (receiver_exit_code); }
int main(int argc, char *argv[]) { int port, srvport, retval; datagram_t datagram; // Check command line arguments if (argc != 3) { fprintf(stderr, "usage: %s <localport> <serverport>\n", argv[0]); exit(-1); } port = atoi(argv[1]); srvport = atoi(argv[2]); init_datagram_service(port, DEBUG_ALL); // Prepare datagram bzero(&datagram, sizeof(datagram)); strcpy(datagram.srcaddr, "128.2.13.139"); // These should be command line inputs strcpy(datagram.dstaddr, "128.2.13.139"); // I am just being lazy here :-). // replace with your ip values before running datagram.srcport = port; datagram.dstport = srvport; strcpy(datagram.data, "Hello World!"); datagram.size = 12; // Send datagram retval = send_datagram(&datagram); if (retval < 0) { perror("Send error"); } printf("Sent %d bytes\n", retval); return 0; }
void Host::network_tick() { while (!commands_.empty() && commands_.front().get_time() == virtual_time_) { Command command = commands_.front(); commands_.pop(); std::string cmd_string = command.get_command(); if (service_type_ == IRCC) application_->process_command(cmd_string, *this); } if (!send_datagram_queue.empty()) if (send_datagram(send_datagram_queue.front())) send_datagram_queue.pop(); if (!received_datagram_queue.empty()) { // Recolhe os datagramas da fila de datagramas recebidos (provavelmente // vai ser só 1 por vez, mas né) e manipula ele do jeito que precisa. // Provavelmente o melhor a se fazer é algo como, enviar para a // aplicação, que daí ela processa esse datagrama e depois converte isso // em novos datagramas pra serem enviados. application_->receive_datagram(received_datagram_queue.front(), *this); received_datagram_queue.pop(); } virtual_time_ += 1; }
void MDNetworkParticipant::handle_datagram(DatagramHandle dg, DatagramIterator&) { logger().trace() << "MDNetworkParticipant sending to downstream MD" << std::endl; try { send_datagram(dg); } catch(boost::system::system_error &e) { logger().warning() << "Received a system error while sending a datagram to a network " "participant (the participant may have lost connection)." << std::endl; return; } }
/*\brief Send a sequence of datagrams with 1 second period \note Th function employs dgram_port and dgrams_no global variables \retval -1 if error \retval 0 if sent */ int run_sender( ) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("Sending %d datagrams on port %d\n"), dgrams_no, dgram_port)); ACE_SOCK_Dgram_Bcast socket; if (socket.open (ACE_Addr::sap_any) != -1) { while (dgrams_no-- != 0) { if (send_datagram (socket, dgrams_no) < 0) break; ACE_OS::sleep (1); } socket.close (); return (0); } ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Cannot open broadcast socket")), -1); }
void InternalConnection::set_conn_name(std::string name) { Datagram dg(CONTROL_SET_CON_NAME); dg.add_string(name); send_datagram(dg); }
void InternalConnection::set_conn_url(std::string uri) { Datagram dg(CONTROL_SET_CON_URL); dg.add_string(uri); send_datagram(dg); }
void InternalConnection::clear_post_removes() { send_datagram(Datagram(CONTROL_CLEAR_POST_REMOVES)); }
void InternalConnection::add_post_remove(const Datagram &post) { Datagram dg(CONTROL_ADD_POST_REMOVE); dg.add_blob(post); send_datagram(dg); }
void InternalConnection::unsubscribe_channel(channel_t channel) { Datagram dg(CONTROL_REMOVE_CHANNEL); dg.add_channel(channel); send_datagram(dg); }
// handle_datagram is the handler for datagrams received from the Astron cluster void Client::handle_datagram(Datagram &dg, DatagramIterator &dgi) { channel_t sender = dgi.read_uint64(); uint16_t msgtype = dgi.read_uint16(); switch(msgtype) { case CLIENTAGENT_EJECT: { uint16_t reason = dgi.read_uint16(); std::string error_string = dgi.read_string(); send_disconnect(reason, error_string); return; } break; case CLIENTAGENT_DROP: { handle_drop(); return; } break; case CLIENTAGENT_SET_STATE: { m_state = (ClientState)dgi.read_uint16(); } break; case STATESERVER_OBJECT_SET_FIELD: { uint32_t do_id = dgi.read_uint32(); if(!lookup_object(do_id)) { m_log->warning() << "Received server-side field update for unknown object " << do_id << std::endl; return; } if(sender != m_channel) { uint16_t field_id = dgi.read_uint16(); handle_set_field(do_id, field_id, dgi); } } break; case STATESERVER_OBJECT_DELETE_RAM: { uint32_t do_id = dgi.read_uint32(); if(!lookup_object(do_id)) { m_log->warning() << "Received server-side object delete for unknown object " << do_id << std::endl; return; } if(m_seen_objects.find(do_id) != m_seen_objects.end()) { m_seen_objects.erase(do_id); m_id_history.insert(do_id); handle_remove_object(do_id); } if(m_owned_objects.find(do_id) != m_owned_objects.end()) { m_owned_objects.erase(do_id); handle_remove_ownership(do_id); } m_dist_objs.erase(do_id); } break; case STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER: case STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED: { uint32_t do_id = dgi.read_uint32(); uint32_t parent = dgi.read_uint32(); uint32_t zone = dgi.read_uint32(); uint16_t dc_id = dgi.read_uint16(); m_owned_objects.insert(do_id); if(m_dist_objs.find(do_id) == m_dist_objs.end()) { VisibleObject obj; obj.id = do_id; obj.parent = parent; obj.zone = zone; obj.dcc = g_dcf->get_class(dc_id); m_dist_objs[do_id] = obj; } handle_add_ownership(do_id, parent, zone, dc_id, dgi, true); } break; case CLIENTAGENT_SET_CLIENT_ID: { if(m_channel != m_allocated_channel) { unsubscribe_channel(m_channel); } m_channel = dgi.read_uint64(); subscribe_channel(m_channel); } break; case CLIENTAGENT_SEND_DATAGRAM: { Datagram forward; forward.add_data(dgi.read_string()); send_datagram(forward); } break; case CLIENTAGENT_OPEN_CHANNEL: { subscribe_channel(dgi.read_uint64()); } break; case CLIENTAGENT_CLOSE_CHANNEL: { unsubscribe_channel(dgi.read_uint64()); } break; case CLIENTAGENT_ADD_POST_REMOVE: { add_post_remove(dgi.read_string()); } break; case CLIENTAGENT_CLEAR_POST_REMOVES: { clear_post_removes(); } break; case STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED: case STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER: { uint32_t do_id = dgi.read_uint32(); uint32_t parent = dgi.read_uint32(); uint32_t zone = dgi.read_uint32(); uint16_t dc_id = dgi.read_uint16(); if(m_owned_objects.find(do_id) != m_owned_objects.end() || m_seen_objects.find(do_id) != m_seen_objects.end()) { return; } if(m_dist_objs.find(do_id) == m_dist_objs.end()) { VisibleObject obj; obj.id = do_id; obj.dcc = g_dcf->get_class(dc_id); obj.parent = parent; obj.zone = zone; m_dist_objs[do_id] = obj; } m_seen_objects.insert(do_id); handle_add_object(do_id, parent, zone, dc_id, dgi, msgtype == STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER); // TODO: This is a tad inefficient as it checks every pending interest. // In practice, there shouldn't be many add-interest operations active // at once, however. std::list<uint32_t> deferred_deletes; for(auto it = m_pending_interests.begin(); it != m_pending_interests.end(); ++it) { if(it->second->is_ready(m_dist_objs)) { handle_interest_done(it->second->m_interest_id, it->second->m_client_context); deferred_deletes.push_back(it->first); } } for(auto it = deferred_deletes.begin(); it != deferred_deletes.end(); ++it) { m_pending_interests.erase(*it); } } break; case STATESERVER_OBJECT_GET_ZONES_COUNT_RESP: { uint32_t context = dgi.read_uint32(); uint32_t count = dgi.read_uint32(); if(m_pending_interests.find(context) == m_pending_interests.end()) { m_log->error() << "Received GET_ZONES_COUNT_RESP for unknown context " << context << std::endl; return; } m_pending_interests[context]->store_total(count); if(m_pending_interests[context]->is_ready(m_dist_objs)) { handle_interest_done(m_pending_interests[context]->m_interest_id, m_pending_interests[context]->m_client_context); m_pending_interests.erase(context); } } break; case STATESERVER_OBJECT_CHANGING_LOCATION: { uint32_t do_id = dgi.read_uint32(); uint32_t n_parent = dgi.read_uint32(); uint32_t n_zone = dgi.read_uint32(); dgi.read_uint32(); // Old parent; we don't care about this. dgi.read_uint32(); // Old zone; we don't care about this. bool disable = true; for(auto it = m_interests.begin(); it != m_interests.end(); ++it) { Interest &i = it->second; for(auto it2 = i.zones.begin(); it2 != i.zones.end(); ++it2) { if(*it2 == n_zone) { disable = false; break; } } } if(m_dist_objs.find(do_id) != m_dist_objs.end()) { m_dist_objs[do_id].parent = n_parent; m_dist_objs[do_id].zone = n_zone; } if(disable && m_owned_objects.find(do_id) == m_owned_objects.end()) { handle_remove_object(do_id); m_seen_objects.erase(do_id); m_dist_objs.erase(do_id); } else { handle_change_location(do_id, n_parent, n_zone); } } break; default: m_log->error() << "Recv'd unk server msgtype " << msgtype << std::endl; } }