udp_nio.java.txt

来自「JGRoups源码」· 文本 代码 · 共 1,513 行 · 第 1/4 页

TXT
1,513
字号
        }        str=props.getProperty("bind_addrs_exclude");        if(str != null) {            str=str.trim();            exclude_list=Util.parseCommaDelimitedStrings(str);            props.remove("bind_addrs_exclude");        }        str=props.getProperty("bind_port");        if(str != null) {            local_bind_port=Integer.parseInt(str);            props.remove("bind_port");        }        str=props.getProperty("start_port");        if(str != null) {            local_bind_port=Integer.parseInt(str);            props.remove("start_port");        }        str=props.getProperty("port_range");        if(str != null) {            port_range=Integer.parseInt(str);            props.remove("port_range");        }        str=props.getProperty("mcast_addr");        if(str != null) {            mcast_addr_name=str;            props.remove("mcast_addr");        }        str=props.getProperty("mcast_port");        if(str != null) {            mcast_port=Integer.parseInt(str);            props.remove("mcast_port");        }        str=props.getProperty("ip_mcast");        if(str != null) {            ip_mcast=Boolean.valueOf(str).booleanValue();            props.remove("ip_mcast");        }        str=props.getProperty("ip_ttl");        if(str != null) {            ip_ttl=Integer.parseInt(str);            props.remove("ip_ttl");        }        str=props.getProperty("mcast_send_buf_size");        if(str != null) {            mcast_send_buf_size=Integer.parseInt(str);            props.remove("mcast_send_buf_size");        }        str=props.getProperty("mcast_recv_buf_size");        if(str != null) {            mcast_recv_buf_size=Integer.parseInt(str);            props.remove("mcast_recv_buf_size");        }        str=props.getProperty("ucast_send_buf_size");        if(str != null) {            ucast_send_buf_size=Integer.parseInt(str);            props.remove("ucast_send_buf_size");        }        str=props.getProperty("ucast_recv_buf_size");        if(str != null) {            ucast_recv_buf_size=Integer.parseInt(str);            props.remove("ucast_recv_buf_size");        }        str=props.getProperty("use_packet_handler");        if(str != null) {            use_packet_handler=Boolean.valueOf(str).booleanValue();            props.remove("use_packet_handler");        }        // determine mcast_addr        mcast_addr=new InetSocketAddress(mcast_addr_name, mcast_port);        // handling of bind_addrs        if(bind_addrs == null)            bind_addrs=new ArrayList();        if(bind_addrs.size() == 0) {            try {                String default_bind_addr=determineDefaultBindInterface();                bind_addrs.add(default_bind_addr);            }            catch(SocketException ex) {                if(log.isErrorEnabled()) log.error("failed determining the default bind interface: " + ex);            }        }        if(exclude_list != null) {            bind_addrs.removeAll(exclude_list);        }        if(bind_addrs.size() == 0) {            if(log.isErrorEnabled()) log.error("no valid bind interface found, unable to listen for network traffic");            return false;        }        else {                if(log.isInfoEnabled()) log.info("bind interfaces are " + bind_addrs);        }        if(props.size() > 0) {            log.error("UDP_NIO.setProperties(): the following properties are not recognized: " + props);            return false;        }        return true;    }    /**     * This prevents the up-handler thread to be created, which essentially is superfluous:     * messages are received from the network rather than from a layer below.     * DON'T REMOVE !      */    public void startUpHandler() {    }    /**     * handle the UP event.     *      * @param evt - the event being send from the stack     */    public void up(Event evt) {        passUp(evt);        switch(evt.getType()) {            case Event.CONFIG:                passUp(evt);                 if(log.isInfoEnabled()) log.info("received CONFIG event: " + evt.getArg());                handleConfigEvent((HashMap)evt.getArg());                return;        }        passUp(evt);    }    /**     * 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;        }        msg=(Message)evt.getArg();        if(udp_hdr != null && udp_hdr.channel_name != 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 == false) {                //sends a separate UDP message to each address                sendMultipleUdpMessages(msg, members);                return;            }        }        try {            sendUdpMessage(msg); // either unicast (dest != null) or multicast (dest == null)        }        catch(Exception e) {            if(log.isErrorEnabled()) log.error("exception=" + e + ", msg=" + msg + ", mcast_addr=" + mcast_addr);        }    }    /*--------------------------- End of Protocol interface -------------------------- */    /* ------------------------------ Private Methods -------------------------------- */    void handleMessage(Message msg) {    }    /**     * Processes a packet read from either the multicast or unicast socket. Needs to be synchronized because     * mcast or unicast socket reads can be concurrent     */    void handleIncomingUdpPacket(byte[] data, SocketAddress sender) {        ByteArrayInputStream inp_stream;        ObjectInputStream    inp;        Message              msg=null;        UdpHeader            hdr=null;        Event                evt;        Address              dst, src;        short                version;        try {            // skip the first n bytes (default: 4), this is the version info            inp_stream=new ByteArrayInputStream(data);            inp=new ObjectInputStream(inp_stream);            version=inp.readShort();            if(Version.compareTo(version) == false) {                if(warn)                    log.warn("packet from " + sender + " has different version (" + version +                               ") from ours (" + Version.version + "). This may cause problems");            }            msg=new Message();            msg.readExternal(inp);            dst=msg.getDest();            src=msg.getSrc();            if(src == null) {                if(log.isErrorEnabled()) log.error("sender's address is null");            }            else {                ((LogicalAddress)src).setPrimaryPhysicalAddress(sender);            }            // discard my own multicast loopback copy            if((dst == null || dst.isMulticastAddress()) && src != null && local_addr.equals(src)) {                if(trace)                    log.trace("discarded own loopback multicast packet");                // System.out.println("-- discarded " + msg.getObject());                return;            }            evt=new Event(Event.MSG, msg);            if(trace)                log.trace("Message is " + msg + ", headers are " + msg.getHeaders());            /* 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());            hdr=(UdpHeader)msg.removeHeader(name);        } catch(Throwable e) {            if(log.isErrorEnabled()) log.error("exception=" + Util.getStackTrace(e));            return;        }        if(hdr != null) {            /* Discard all messages destined for a channel with a different name */            String ch_name=null;            if(hdr.channel_name != null)                ch_name=hdr.channel_name;            // Discard if message's group name is not the same as our group name unless the            // message is a diagnosis message (special group name DIAG_GROUP)            if(ch_name != null && group_name != null && !group_name.equals(ch_name) &&                    !ch_name.equals(Util.DIAG_GROUP)) {                    if(warn) log.warn("discarded message from different group (" +                            ch_name + "). Sender was " + msg.getSrc());                return;            }        }        passUp(evt);    }    /**     * Send a message to the address specified in dest     */    void sendUdpMessage(Message msg) throws Exception {        Address            dest, src;        ObjectOutputStream out;        byte               buf[];        DatagramPacket     packet;        Message            copy;        Event              evt; // for loopback messages        dest=msg.getDest();  // if non-null: unicast, else multicast        src=msg.getSrc();        if(src == null) {            src=local_addr_canonical; // no physical addresses present            msg.setSrc(src);        }        if(trace)            log.trace("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(dest == null || dest.isMulticastAddress() || dest.equals(local_addr)) {            copy=msg.copy();            copy.removeHeader(name);            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) log.trace("looped back local message " + copy);            // System.out.println("\n-- passing up packet id=" + copy.getObject());            passUp(evt);            // System.out.println("-- passed up packet id=" + copy.getObject());            if(dest != null && !dest.isMulticastAddress())                return; // it is a unicast message to myself, no need to put on the network        }        out_stream.reset();        out=new ObjectOutputStream(out_stream);        out.writeShort(Version.version);        msg.writeExternal(out);        out.flush(); // needed if out buffers its output to out_stream        buf=out_stream.toByteArray();        packet=new DatagramPacket(buf, buf.length, mcast_addr);        //System.out.println("-- sleeping 4 secs");        // Thread.sleep(4000);        // System.out.println("\n-- sending packet " + msg.getObject());        ct.send(packet);        // System.out.println("-- sent " + msg.getObject());    }    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) {                if(log.isDebugEnabled()) log.debug("exception=" + e);            }        }    }////    /**//     * Workaround for the problem encountered in certains JDKs that a thread listening on a socket//     * cannot be interrupted. Therefore we just send a dummy datagram packet so that the thread 'wakes up'//     * and realizes it has to terminate. Should be removed when all JDKs support Thread.interrupt() on//     * reads. Uses send_sock t send dummy packet, so this socket has to be still alive.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?