上一篇日志写了些常见的概念,这一篇想说一下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:否 2:2位变长, 3:3位变长*/
int datatyp; /*0 -- string, 1 -- int, 2 -- binary*/
char *data; /*存放具体值*/
int attribute; /*保留*/
} ;
我们可以直接根据协议的要求把ISO8583FieldAttribute类换为Struct类型,名字也估且叫ISO8583 Structure吧,完整 的程序如下
由于每个域都会有ISO8583 Structure的定义,那这样我们可以看看Class Field{}的雏形
public class ISO8583Field
{
public ISO8583Structure _ISO8583Structure;
}
ISO8583Package组包类中初始化需要的域
这时候当我们拿到一个实际开发任务的时候,比如某个银行给你的接口要求如下
位 |
数据元 |
数据类型 |
发送方及数值 |
备注 |
|
T→P |
P→T |
||||
0 |
信息类型 |
N4 |
0800 |
0810 |
|
1 |
位元表 |
B64 |
M |
M |
|
3 |
处理码 |
N6 |
M |
M |
XXXXXX |
11 |
交易流水 |
N6 |
M |
M |
终端交易流水 |
这段报文需要0,1,3,11域的数据,我们在组包的时候初始化一些基本参数,如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);
}
}
在构造函数里进行域数据赋值。
这里我所写的都是一些想法,跟实际情况有很大差距,实际跟银联接口无任何关系,只是在这里说一下拿到需求以后我们写程序的想法