zoukankan      html  css  js  c++  java
  • 银联接口开发随笔(2)

          上一篇日志写了些常见的概念,这一篇想说一下ISO8583协议,因为在银行交易中这个协议是关键,网络间传输的都是基于该协议的数据,网上介绍该协议的文章比较多,这里找到一篇比较好的(http://blog.csdn.net/AndrewWang79/article/details/3859176)。我没有别的可以多讲的,只想讲讲如何设计一个协议处理程序的思路

            在了解了协议以后我们会发现,网络间传输的数据包是每个域的数据组成,每个数据又会拥有各自的属性,比如像协议中提到的第二域:

            / *   FLD   2   */   {0,"PRIMARY   ACCOUNT   NUMBER   ",   22,   0,   2,   1,   NULL,0},

     0表示数据类型,22表示该域的总长度22个字节。

     在了解这样的情况以后,我们脑袋中自然会想到三个名词,数据包,域字段,域字段属性,这里稍等一下,在我们读过的关于面像对像设计的书中是不是都会有提到,在我们观察事物的时候,总是将名字与类联系在一起?我们这里也不仿一试,估且定义三个类

     Class ISO8583Package{},

     Class ISO8583Field{},

     Class ISO8583FieldAttribute{}

         这样用Package表示报文,Field表示报文中的每个域,而FieldAttribute表示每一个域的类型。根据协议的要求,每个域的特性如下

          typedef struct ISO8583  
         {  
           int bit_flag; /*
    域数据类型0 -- string, 1 -- int, 2 -- binary*/  
           char *data_name; /*
    域名*/  
           int length; /*
    数据域长度*/  
           int length_in_byte;/*
    实际长度(如果是变长)*/  
           int variable_flag; /*
    是否变长标志0:否 22位变长, 33位变长*/  
           int datatyp; /*0 -- string, 1 -- int, 2 -- binary*/  
           char *data; /*
    存放具体值*/  
           int attribute; /*
    保留*/  
         } ;

       我们可以直接根据协议的要求把ISO8583FieldAttribute类换为Struct类型,名字也估且叫ISO8583 Structure吧,完整 的程序如下

       

     public struct ISO8583Structure
        {
            
    public int bit_flag; /*域数据类型0 -- string, 1 -- int, 2 -- binary*/
            
    public string data_name; /*域名*/
            
    public int length; /*数据域长度*/
            
    public int length_in_byte;/*实际长度(如果是变长)*/
            
    public int variable_flag; /*是否变长标志0:否 2:2位变长, 3:3位变长*/
            
    public int datatyp; /*0 -- string, 1 -- int, 2 -- binary*/
            
    public string data; /*存放具体值*/
            
    public int attribute; /*保留*/

        }

         由于每个域都会有ISO8583 Structure的定义,那这样我们可以看看Class Field{}的雏形

           public class ISO8583Field

          {

           public ISO8583Structure _ISO8583Structure;

    }

         ISO8583Package组包类中初始化需要的域

       

    View Code
      public class ISO8583Package
        {
            
    //用于保存初始结构
            public Dictionary<int, ISO8583Structure> ISO8583Collection;
            
    //用于保存存实际报文域数据
            public Dictionary<int, ISO8583Field> ISO8583CollectionData;

            
    public ISO8583Package()
            {
                
    //初始化默认位图类型
                initDefaultField();

            }

            
    public byte[] GetField(int i)
            {
                
    return null;
            }
            
    public byte[] GetISO8583Package()
            {
                
    return null;
            }

            
    public bool SetField(ISO8583Field field)
            {
                
    return false;
            }
            
    public bool SetBitMap()
            {
                
    return false;
            }

            
    /// <summary>
            
    /// 根据域索引设置值
            
    /// </summary>
            
    /// <param name="FieldValue"></param>
            
    /// <param name="i"></param>
            public void SetField(string FieldValue, int i)
            {
                ISO8583Field field 
    = new ISO8583Field();
                field._ISO8583Structure 
    = ISO8583Collection[i];
                field._ISO8583Structure.data 
    = FieldValue;

            }

            
    /// <summary>
            
    /// 根据银行接口要求来初始化
            
    /// </summary>
            private void initDefaultField()
            {
                
    //初始化ISO8583Collection,根据协议要求采取默认初始化
                ISO8583Structure structure1;
                structure1.bit_flag 
    = 1/*域数据类型0 -- string, 1 -- int, 2 -- binary*/
                structure1.data_name 
    = "信息类型"/*域名*/
                structure1.length 
    = 4/*数据域长度*/
                structure1.length_in_byte 
    = 0;/*实际长度(如果是变长)*/
                structure1.variable_flag 
    = 0/*是否变长标志0:否 2:2位变长, 3:3位变长*/
                structure1.datatyp 
    = 1/*0 -- string, 1 -- int, 2 -- binary*/
                structure1.data 
    = ""/*存放具体值*/
                structure1.attribute 
    = 0/*保留*/
                ISO8583Collection.Add(
    1,structure1);

                ISO8583Structure structure3;
                structure3.bit_flag 
    = 0/*域数据类型0 -- string, 1 -- int, 2 -- binary*/
                structure3.data_name 
    = "处理码"/*域名*/
                structure3.length 
    = 6/*数据域长度*/
                structure3.length_in_byte 
    = 0;/*实际长度(如果是变长)*/
                structure3.variable_flag 
    = 0/*是否变长标志0:否 2:2位变长, 3:3位变长*/
                structure3.datatyp 
    = 0/*0 -- string, 1 -- int, 2 -- binary*/
                structure3.data 
    = ""/*存放具体值*/
                structure3.attribute 
    = 0/*保留*/
                ISO8583Collection.Add(
    1, structure3);

                ISO8583Structure structure11;
                structure11.bit_flag 
    = 0/*域数据类型0 -- string, 1 -- int, 2 -- binary*/
                structure11.data_name 
    = "终端流水"/*域名*/
                structure11.length 
    = 6/*数据域长度*/
                structure11.length_in_byte 
    = 0;/*实际长度(如果是变长)*/
                structure11.variable_flag 
    = 0/*是否变长标志0:否 2:2位变长, 3:3位变长*/
                structure11.datatyp 
    = 1/*0 -- string, 1 -- int, 2 -- binary*/
                structure11.data 
    = ""/*存放具体值*/
                structure11.attribute 
    = 0/*保留*/
                ISO8583Collection.Add(
    1, structure11);
            }

     

    这时候当我们拿到一个实际开发任务的时候,比如某个银行给你的接口要求如下

    数据元

    数据类型

    发送方及数值

    备注

    T→P

    P→T

    0

    信息类型

    N4

    0800

    0810

    1

    位元表

    B64

    M

    M

    3

    处理码

    N6

    M

    M

    XXXXXX

    11

    交易流水

    N6

    M

    M

    终端交易流水

          这段报文需要01311域的数据,我们在组包的时候初始化一些基本参数,如ISO8583Package类的构造函数里所看到的,在实际使用过程中再重新设置这些值就可以了。

    现在我们来看一下使用的类的情况,先看一下代码示例,如下

    public class ISO8583Base

        {

           

            ISO8583Package _ISO8583Package;

           

            public ISO8583Base()

            {

                _ISO8583Package = new ISO8583Package();

            }

            /// <summary>

            /// 根据银行接口要求设置域值

            /// </summary>

            /// <param name="CommandType"></param>

            /// <param name="ProcessCode"></param>

            /// <param name="SerialNaumber"></param>

            public ISO8583Base(string CommandType,string ProcessCode,string SerialNaumber)

            {

                _ISO8583Package.SetField(CommandType, 1);

                _ISO8583Package.SetField(ProcessCode, 3);

                _ISO8583Package.SetField(SerialNaumber, 11);

            }

    }

    在构造函数里进行域数据赋值。

    这里我所写的都是一些想法,跟实际情况有很大差距,实际跟银联接口无任何关系,只是在这里说一下拿到需求以后我们写程序的想法

  • 相关阅读:
    RabbitMQ
    虚拟化解决方案
    如何制作Windows镜像
    2018-2019-2 网络对抗技术 20165202 Exp9 Web安全基础
    2018-2019-2 网络对抗技术 20165202 Exp8 Web基础
    2018-2019-2 网络对抗技术 20165202 Exp7 网络欺诈防范
    2018-2019-2 网络对抗技术 20165202 Exp6 信息搜集与漏洞扫描
    2018-2019-2 网络对抗技术 20165202 Exp5 MSF基础应用
    2018-2019-2 网络对抗技术 20165202 Exp4 恶意代码分析
    2018-2019-2 网络对抗技术 20165202 Exp3 免杀原理与实践
  • 原文地址:https://www.cnblogs.com/zycblog/p/2105344.html
Copyright © 2011-2022 走看看