/** Send a message to the address specified in dest */ void sendUdpMessage(Message msg) throws Exception { IpAddress dest; Message copy; Event evt; dest = (IpAddress) msg.getDest(); // guaranteed not to be null setSourceAddress(msg); if (Trace.debug) { Trace.debug( "UDP.sendUdpMessage()", "sending message to " + msg.getDest() + " (src=" + msg.getSrc() + "), headers are " + msg.getHeaders()); // Don't send if destination is local address. Instead, switch dst and src and put in // up_queue. // If multicast message, loopback a copy directly to us (but still multicast). Once we receive // this, // we will discard our own multicast message } if (loopback && (dest.equals(local_addr) || dest.isMulticastAddress())) { copy = msg.copy(); copy.removeHeader(name); copy.setSrc(local_addr); copy.setDest(dest); evt = new Event(Event.MSG, copy); /* Because Protocol.up() is never called by this bottommost layer, we call up() directly in the observer. This allows e.g. PerfObserver to get the time of reception of a message */ if (observer != null) { observer.up(evt, up_queue.size()); } if (Trace.debug) { Trace.info("UDP.sendUdpMessage()", "looped back local message " + copy); } passUp(evt); if (!dest.isMulticastAddress()) { return; } } if (use_outgoing_packet_handler) { outgoing_queue.add(msg); return; } send(msg); }
void sendMultipleUdpMessages(Message msg, Vector dests) { Address dest; for (int i = 0; i < dests.size(); i++) { dest = (Address) dests.elementAt(i); msg.setDest(dest); try { sendUdpMessage(msg); } catch (Exception e) { Trace.debug("UDP.sendMultipleUdpMessages()", "exception=" + e); } } }
/** * Caller by the layer above this layer. Usually we just put this Message into the send queue and * let one or more worker threads handle it. A worker thread then removes the Message from the * send queue, performs a conversion and adds the modified Message to the send queue of the layer * below it, by calling Down). */ public void down(Event evt) { Message msg; Object dest_addr; if (evt.getType() != Event.MSG) { // unless it is a message handle it and respond handleDownEvent(evt); return; } // ****************** profiling ****************** /*if(num_msgs == 0) { start=System.currentTimeMillis(); num_msgs++; } else if(num_msgs >= 1000) { stop=System.currentTimeMillis(); long total_time=stop-start; double msgs_per_msec=num_msgs / (double)total_time; if(Trace.trace) Trace.info("UDP.down.profile()", "total_time=" + total_time + ", msgs/ms=" + msgs_per_msec); num_msgs=0; } else { num_msgs++; }*/ // ****************** profiling ****************** msg = (Message) evt.getArg(); if (udp_hdr != null && udp_hdr.group_addr != null) { // added patch by Roland Kurmann (March 20 2003) msg.putHeader(name, udp_hdr); } dest_addr = msg.getDest(); // Because we don't call Protocol.passDown(), we notify the observer directly (e.g. // PerfObserver). // This way, we still have performance numbers for UDP if (observer != null) { observer.passDown(evt); } if (dest_addr == null) { // 'null' means send to all group members if (ip_mcast) { if (mcast_addr == null) { Trace.error( "UDP.down()", "dest address of message is null, and " + "sending to default address fails as mcast_addr is null, too !" + " Discarding message " + Util.printEvent(evt)); return; } // if we want to use IP multicast, then set the destination of the message msg.setDest(mcast_addr); } else { // sends a separate UDP message to each address sendMultipleUdpMessages(msg, members); return; } } try { sendUdpMessage(msg); } catch (Exception e) { Trace.error("UDP.down()", "exception=" + e + ", msg=" + msg + ", mcast_addr=" + mcast_addr); } }