银联接口开发随笔(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);

        }

 

}

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

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

你可能感兴趣的:(接口)