少妇被躁爽到高潮无码人狍大战,欧洲亚洲国产精华液,色狠狠色噜噜av天堂一区,人人妻,一区二区三区,色偷偷wwww88888

首頁 - 關(guān)于研博 - 技術(shù)筆記 - IEC104協(xié)議解析
IEC104協(xié)議解析
2025.03.07

一、IEC104協(xié)議核心特性與應(yīng)用場景

 IEC104(IEC 60870-5-104)是電力系統(tǒng)中廣泛使用的通信協(xié)議,基于TCP/IP實(shí)現(xiàn)主從站(SCADA與RTU/變電站設(shè)備)的實(shí)時數(shù)據(jù)交互‌。其核心功能包括:

1.四遙操作‌:

  • 遙測‌(YC):采集電壓、電流等模擬量數(shù)據(jù)(如類型標(biāo)識0x0D)‌。

  • 遙信‌(YX):監(jiān)測開關(guān)狀態(tài)等數(shù)字量信號(如M_SP_NA_1單點(diǎn)遙信)‌。

  • 遙控‌(YK):遠(yuǎn)程控制斷路器分合閘(如C_SC_NA_1指令)‌。

  • 遙調(diào)‌(YT):參數(shù)調(diào)節(jié)(如變壓器分接頭調(diào)整)‌。

2.‌協(xié)議分層‌:

  • APCI‌(應(yīng)用協(xié)議控制信息):包含啟動字符0x68、長度域及控制域(I/S/U幀標(biāo)識)‌。

  • ASDU‌(應(yīng)用服務(wù)數(shù)據(jù)單元):承載業(yè)務(wù)數(shù)據(jù)(如公共地址、傳送原因、信息體列表)‌。 

二、 編解碼實(shí)現(xiàn) 

(一)解碼器

public class IEC104FrameDecoder extends LengthFieldBasedFrameDecoder {
    private static final int MAX_FRAME_LENGTH = 253;
    private static final int LENGTH_FIELD_OFFSET = 1;
    private static final int LENGTH_FIELD_LENGTH = 1;

    public IEC104FrameDecoder() {
        super(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, 0, 0); // ?:ml-citation{ref="1,2" data="citationList"}
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        // 校驗(yàn)啟動字符
        if (in.getByte(in.readerIndex()) != 0x68) {
            ctx.close();
            throw new ProtocolException("Invalid start byte 0x" + 
                                        Integer.toHexString(in.getByte(in.readerIndex()))); // ?:ml-citation{ref="2,5" data="citationList"}
        }

        // 動態(tài)分割報(bào)文
        ByteBuf frame = (ByteBuf) super.decode(ctx, in);
        if (frame == null) return null;

        // 解析APCI
        frame.readByte(); // 跳過0x68
        int apduLength = frame.readUnsignedByte();
        if (frame.readableBytes() < apduLength) {
            return null; // 等待完整報(bào)文?:ml-citation{ref="2,5" data="citationList"}
        }

        ByteBuf apduContent = frame.readSlice(apduLength);
        return parseAPDU(apduContent);
    }

    private APDU parseAPDU(ByteBuf buf) {
        // 解析控制域(4字節(jié))
        int ctrl1 = buf.readUnsignedByte();
        int ctrl2 = buf.readUnsignedByte();
        int ctrl3 = buf.readUnsignedByte();
        int ctrl4 = buf.readUnsignedByte();

        ControlFieldType type;
        int sendSeq = 0, recvSeq = 0;
        UFrameCommand uCommand = null;

        // I幀(低比特位為0)
        if ((ctrl1 & 0x01) == 0) { // ?:ml-citation{ref="2,4" data="citationList"}
            type = ControlFieldType.I_FRAME;
            sendSeq = ((ctrl1 & 0xFE) >> 1) | (ctrl2 << 7);
            recvSeq = ((ctrl3 & 0xFE) >> 1) | (ctrl4 << 7);
        } 
            // S幀(低2比特為01)
        else if ((ctrl1 & 0x03) == 0x01) { // ?:ml-citation{ref="2,4" data="citationList"}
            type = ControlFieldType.S_FRAME;
            recvSeq = ((ctrl3 & 0xFE) >> 1) | (ctrl4 << 7);
        } 
            // U幀(低2比特為11)
        else { // ?:ml-citation{ref="2,4" data="citationList"}
            type = ControlFieldType.U_FRAME;
            uCommand = UFrameCommand.fromBytes(ctrl1, ctrl2);
        }

        // 解析ASDU(僅I幀攜帶數(shù)據(jù))
        ASDU asdu = null;
        if (type == ControlFieldType.I_FRAME && buf.readableBytes() >= 6) {
            asdu = new ASDU();
            asdu.setTypeId(buf.readUnsignedByte()); // 類型標(biāo)識?:ml-citation{ref="2,3" data="citationList"}
            asdu.setVariableStruct(buf.readUnsignedByte()); // 可變結(jié)構(gòu)限定詞?:ml-citation{ref="2,3" data="citationList"}
            asdu.setCause(buf.readUnsignedShortLE()); // 傳送原因(小端)?:ml-citation{ref="2,5" data="citationList"}
            asdu.setCommonAddress(buf.readUnsignedShortLE()); // 公共地址?:ml-citation{ref="2,5" data="citationList"}

            // 解析信息體(示例:遙測數(shù)據(jù))
            int objCount = asdu.getVariableStruct() & 0x7F; // SQ=0時取低7位?:ml-citation{ref="2,3" data="citationList"}
            for (int i = 0; i < objCount; i++) {
                InfoObject obj = new InfoObject();
                obj.setAddress(buf.readUnsignedMediumLE()); // 3字節(jié)地址小端?:ml-citation{ref="2,5" data="citationList"}
                if (asdu.getTypeId() == 0x0D) { // 浮點(diǎn)型遙測
                    obj.setValue(buf.readFloatLE()); // ?:ml-citation{ref="2,3" data="citationList"}
                }
                asdu.addInfoObject(obj);
            }
        }

        return new APDU(type, sendSeq, recvSeq, uCommand, asdu);
    }
}

(二) 編碼器

public class IEC104Encoder extends MessageToByteEncoder {
    private final Recycler bufferRecycler = new Recycler<>() {
        @Override
        protected ByteBuf newObject(Handle handle) {
            return Unpooled.buffer(512);
        }
    };

    @Override
    protected void encode(ChannelHandlerContext ctx, APDU msg, ByteBuf out) {
        ByteBuf apciBuf = bufferRecycler.get();
        try {
            // 構(gòu)建控制域
            switch (msg.getType()) { // ?:ml-citation{ref="2,4" data="citationList"}
                case I_FRAME:
                    apciBuf.writeByte((msg.getSendSeq() << 1) & 0xFF);
                    apciBuf.writeByte((msg.getSendSeq() >> 7) & 0xFF);
                    apciBuf.writeByte((msg.getRecvSeq() << 1) & 0xFF);
                    apciBuf.writeByte((msg.getRecvSeq() >> 7) & 0xFF);
                    break;
                case S_FRAME:
                    apciBuf.writeByte(0x01);
                    apciBuf.writeByte(0x00);
                    apciBuf.writeByte((msg.getRecvSeq() << 1) & 0xFF);
                    apciBuf.writeByte((msg.getRecvSeq() >> 7) & 0xFF);
                    break;
                case U_FRAME:
                    apciBuf.writeByte(msg.getUCommand().getCtrlByte1());
                    apciBuf.writeByte(msg.getUCommand().getCtrlByte2());
                    apciBuf.writeZero(2); // 填充0x00
                    break;
            }

            // 構(gòu)建ASDU(I幀)
            if (msg.getType() == ControlFieldType.I_FRAME && msg.getAsdu() != null) { 
                ASDU asdu = msg.getAsdu();
                apciBuf.writeByte(asdu.getTypeId()); // ?:ml-citation{ref="2,3" data="citationList"}
                apciBuf.writeByte(asdu.getVariableStruct()); 
                apciBuf.writeShortLE(asdu.getCause()); // 小端寫入?:ml-citation{ref="2,5" data="citationList"}
                apciBuf.writeShortLE(asdu.getCommonAddress());

                // 信息體編碼(示例:單點(diǎn)遙信)
                for (InfoObject obj : asdu.getInfoObjects()) {
                    apciBuf.writeMediumLE(obj.getAddress()); // 3字節(jié)小端?:ml-citation{ref="2,5" data="citationList"}
                    if (asdu.getTypeId() == 0x01) { // 單點(diǎn)狀態(tài)
                        apciBuf.writeByte(obj.getStatus() & 0x01); // ?:ml-citation{ref="2,3" data="citationList"}
                    }
                }
            }

            // 構(gòu)建完整APDU
            out.writeByte(0x68); // 啟動字符?:ml-citation{ref="2,5" data="citationList"}
            out.writeByte(apciBuf.readableBytes()); // 長度域?:ml-citation{ref="2,5" data="citationList"}
            out.writeBytes(apciBuf);
        } finally {
            bufferRecycler.recycle(apciBuf);
        }
    }
}

(三) 實(shí)體類

// APDU實(shí)體類(對象池實(shí)現(xiàn))
public class APDU implements Recyclable {
    private static final Recycler recycler = new Recycler<>() { /*...*/ };

    // 控制域字段
    private ControlFieldType type;
    private int sendSeq;
    private int recvSeq;
    private UFrameCommand uCommand;

    // ASDU字段
    private ASDU asdu;

}

// ASDU數(shù)據(jù)結(jié)構(gòu)
public class ASDU {
    private int typeId;          // 類型標(biāo)識?:ml-citation{ref="2,3" data="citationList"}
    private int variableStruct;  // 可變結(jié)構(gòu)限定詞?:ml-citation{ref="2,3" data="citationList"}
    private int cause;           // 傳送原因(低字節(jié)在前)?:ml-citation{ref="2,5" data="citationList"}
    private int commonAddress;   // 公共地址?:ml-citation{ref="2,5" data="citationList"}
    private List infoObjects = new ArrayList<>();
}

// 信息體對象
public class InfoObject {
    private int address;  // 3字節(jié)地址?:ml-citation{ref="2,5" data="citationList"}
    private float value;  // 遙測值
    private byte status;  // 遙信狀態(tài)(0/1)?:ml-citation{ref="2,3" data="citationList"}
}

(四) 關(guān)鍵實(shí)現(xiàn)說明

‌1.動態(tài)沾包處理通過LengthFieldBasedFrameDecoder實(shí)現(xiàn)變長報(bào)文切割,支持最大253字節(jié)APDU報(bào)文‌

‌2.控制域編碼優(yōu)化

  • I幀發(fā)送序號采用左移1位存儲(避免序列號溢出)‌

  • U幀支持STARTDT_ACT/TESTFR_ACT等標(biāo)準(zhǔn)命令‌

3‌.數(shù)據(jù)格式處理

  • 信息體地址使用3字節(jié)‌小端序‌編碼(適配電力設(shè)備規(guī)范)‌

  • 遙測值采用IEEE754浮點(diǎn)型編碼,遙信狀態(tài)用單字節(jié)存儲‌

三、業(yè)務(wù)邏輯處理

  • 總召喚流程‌:主站發(fā)送C_IC_NA_1指令后,從站按點(diǎn)表順序返回所有遙測、遙信數(shù)據(jù),通過多幀I幀傳輸(每幀最大249字節(jié))。

  • 變化數(shù)據(jù)主動上報(bào)‌:從站檢測到數(shù)據(jù)變化時,通過ASDU的‌傳送原因‌字段(如0x03表示突發(fā)上送)觸發(fā)實(shí)時推送‌。

獲取相關(guān)資料
下載地址將會發(fā)送至您填寫的郵箱
相關(guān)新聞
電動汽車GB/T32960-2016協(xié)議介紹開發(fā)
2025-02-21
HJ212環(huán)境監(jiān)測數(shù)據(jù)傳輸協(xié)議
2025-02-14
電能表DLT645協(xié)議解析
2025-02-07
  • 在線客服
  • 電話咨詢
  • 微信
  • 短視頻