OFMessage类

来源:互联网 发布:淘宝新手卖家提取软件 编辑:程序博客网 时间:2024/06/08 07:11

      OFMessage类是openflow 协议消息的基础类,该类包含了所有openflow消息都要使用到的ofp_header。

特定openflow 消息对OFMessage类进行继承和扩展,两者之间的关系如下图:


可见OFMessage基础类的重要性。


以下为带注解的源码:

/***    Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior*    University* *    Licensed under the Apache License, Version 2.0 (the "License"); you may*    not use this file except in compliance with the License. You may obtain*    a copy of the License at**         http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the*    License for the specific language governing permissions and limitations*    under the License.**/package org.openflow.protocol;   //源码包位置import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.ConcurrentHashMap;import net.floodlightcontroller.core.FloodlightContext;import net.floodlightcontroller.core.IFloodlightProviderService;import net.floodlightcontroller.core.IOFSwitch;import net.floodlightcontroller.packet.Ethernet;import org.jboss.netty.buffer.ChannelBuffer;import org.openflow.util.HexString;import org.openflow.util.U16;import org.openflow.util.U32;import org.openflow.util.U8;/** * The base class for all OpenFlow protocol messages. This class contains the * equivalent of the ofp_header which is present in all OpenFlow messages. * * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 3, 2010 * @author Rob Sherwood (rob.sherwood@stanford.edu) - Feb 3, 2010 */public class OFMessage {    public static byte OFP_VERSION = 0x01;     //openflow协议版本 0x01表示 openflow spec 1.0    public static int MINIMUM_LENGTH = 8;      //openflow最小消息长度,8字节,等于消息头大小    protected byte version;               //openflow协议版本     protected OFType type;                //openflow消息类型    protected short length;               //openflow消息长度  包括ofp_header    protected int xid;                    //openflow消息传输id     /*创建ConcurrentHashMap对象,ConcurrentHashMap是一个线程安全的Hash Table,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法*/    private ConcurrentHashMap<String, Object> storage;      /*构造函数,storage初始化为null,版本号为1.0*/    public OFMessage() {        storage = null;        this.version = OFP_VERSION;    }    /*实例化ConcurrentHashMap对象*/    protected synchronized ConcurrentHashMap<String, Object> getMessageStore() {        if (storage == null) {            storage = new ConcurrentHashMap<String, Object>();;        }        return storage;    }    /**     * 获取openflow消息长度(short类型)     */    public short getLength() {        return length;    }    /**     * 获取openflow消息长度 (unsigned short类型)     */    public int getLengthU() {        return U16.f(length);    }    /**     * 设置消息长度(short类型)     */    public OFMessage setLength(short length) {        this.length = length;        return this;    }    /**     * 设置消息长度(unsigned short类型)     */    public OFMessage setLengthU(int length) {        this.length = U16.t(length);        return this;    }    /**     * 获取openflow消息类型     */    public OFType getType() {        return type;    }    /**     * 设置openflow消息类型     */    public void setType(OFType type) {        this.type = type;    }    /**     * 获取openflow消息版本号     */    public byte getVersion() {        return version;    }    /**     * 设置openflow消息版本号     */    public void setVersion(byte version) {        this.version = version;    }    /**     * 获取openflow消息传输id     */    public int getXid() {        return xid;    }    /**     * 设置openflow消息传输id     */    public void setXid(int xid) {        this.xid = xid;    }    /** *从ChannelBuffer缓冲区读取消息     * ChannelBuffer是Netty中比较常用的一个类,其功能类似于字符数组,可以对其进行读写操作     */    public void readFrom(ChannelBuffer data) {        this.version = data.readByte();        this.type = OFType.valueOf(data.readByte());        this.length = data.readShort();        this.xid = data.readInt();    }    /** *将消息写入ChannelBuffer缓冲区     * @param data     */    public void writeTo(ChannelBuffer data) {        data.writeByte(version);        data.writeByte(type.getTypeValue());        data.writeShort(length);        data.writeInt(xid);    }    /**     * 将openflow消息头部转换为字符串 *格式为:"ofmsg:v=$version;t=$type:l=$len:xid=$xid"     */    public String toString() {        return "ofmsg" +            ":v=" + U8.f(this.getVersion()) +            ";t=" + this.getType() +            ";l=" + this.getLengthU() +            ";x=" + U32.f(this.getXid());    }    @Override/**将openflow消息头部信息生成哈希码 */    public int hashCode() {        final int prime = 97;        int result = 1;        result = prime * result + length;        result = prime * result + ((type == null) ? 0 : type.hashCode());        result = prime * result + version;        result = prime * result + xid;        return result;    }/**判断两个openflow消息内容是否一样*/    @Override    public boolean equals(Object obj) {        if (this == obj) {            return true;        }        if (obj == null) {            return false;        }        if (!(obj instanceof OFMessage)) {            return false;        }        OFMessage other = (OFMessage) obj;        if (length != other.length) {            return false;        }        if (type == null) {            if (other.type != null) {                return false;            }        } else if (!type.equals(other.type)) {            return false;        }        if (version != other.version) {            return false;        }        if (xid != other.xid) {            return false;        }        return true;    }    /**将PACKET_IN, PACKET_OUT,FLOW_MOD消息中的关键信息及eth内容转换为字符串,并添加日期,标识等信息**/    public static String getDataAsString(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {        Ethernet eth;        StringBuffer sb =  new StringBuffer("");        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");        Date date = new Date();        sb.append(dateFormat.format(date));        sb.append("      ");        switch (msg.getType()) {            case PACKET_IN:                OFPacketIn pktIn = (OFPacketIn) msg;                sb.append("packet_in          [ ");                sb.append(sw.getStringId());          //DPID                sb.append(" -> Controller");                sb.append(" ]");                sb.append("\ntotal length: ");                sb.append(pktIn.getTotalLength());     //消息总长度                sb.append("\nin_port: ");                sb.append(pktIn.getInPort());           //输入端口号                sb.append("\ndata_length: ");                sb.append(pktIn.getTotalLength() - OFPacketIn.MINIMUM_LENGTH);  //除去消息头的数据的长度                sb.append("\nbuffer: ");                sb.append(pktIn.getBufferId());       //buffer id                // If the conext is not set by floodlight, then ignore.                if (cntx != null) {                // packet type  icmp, arp, etc.                    eth = IFloodlightProviderService.bcStore.get(cntx,                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD);                    if (eth != null)                           sb.append(eth.toString());                   }                break;            case PACKET_OUT:                OFPacketOut pktOut = (OFPacketOut) msg;                sb.append("packet_out         [ ");                sb.append("Controller -> ");                sb.append(HexString.toHexString(sw.getId()));   //DPID                sb.append(" ]");                sb.append("\nin_port: ");                sb.append(pktOut.getInPort());              //输入端口号                sb.append("\nactions_len: ");                sb.append(pktOut.getActionsLength());         //获取Actions长度                if (pktOut.getActions() != null) {                    sb.append("\nactions: ");                    sb.append(pktOut.getActions().toString());   //获取Actions内容                }                break;            case FLOW_MOD:                OFFlowMod fm = (OFFlowMod) msg;                sb.append("flow_mod           [ ");                sb.append("Controller -> ");                sb.append(HexString.toHexString(sw.getId()));    //DPID                sb.append(" ]");                // If the conext is not set by floodlight, then ignore.                if (cntx != null) {                    eth = IFloodlightProviderService.bcStore.get(cntx,                        IFloodlightProviderService.CONTEXT_PI_PAYLOAD);                    if (eth != null)                        sb.append(eth.toString());                }                sb.append("\nADD: cookie: ");                sb.append(fm.getCookie());      //获取cookie  不太明白这是什么                sb.append(" idle: ");                sb.append(fm.getIdleTimeout());  //获取idle time                sb.append(" hard: ");                sb.append(fm.getHardTimeout());   //获取hard time                sb.append(" pri: ");                sb.append(fm.getPriority());      //获取优先级                sb.append(" buf: ");                sb.append(fm.getBufferId());       //获取buffer id                sb.append(" flg: ");                sb.append(fm.getFlags());                if (fm.getActions() != null) {                    sb.append("\nactions: ");                    sb.append(fm.getActions().toString());  //获取Actions内容                }                break;            default:                sb.append("[Unknown Packet]");            //未知消息        }        sb.append("\n\n");        return sb.toString();    }    public static byte[] getData(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {        return OFMessage.getDataAsString(sw, msg, cntx).getBytes();    }}


public boolean equals(Object obj)方法流控图



getDataAsString 方法流控图





0 0
原创粉丝点击