您的位置:首页 > 编程语言 > C#

轻松学习C#开发CMPP2.0协议网关-1

2012-04-17 15:59 316 查看
首先在学习开发C#CMP2.0网关之前,我们首先先要了解,开发CMPP2.0网关需要重点考虑的几点问题,以及简单的说明下CMPP2.0协议。

CMPP2.0协议

CMPP2.0协议采用TCP/IP的通讯协议,开发时一般采用长连接的模式,其封装的协议包主要包括:

1、登录协议包

2、登录应答协议包

3、短信发送协议包

4、短信发送应答协议包

5、上行消息/状态报告协议包

6、上行消息/状态报告应答协议包

7、心跳连接协议包

8、心跳连接应答协议包

每一个协议包都包含消息头与消息体。

CMPP2.0协议网关开发注意问题

1、SP连接移动运营商网关的TCP连接数一般在15个连接,开发的CMPP2.0网关应能支持指定数的连接,在连接崩溃后能够自动恢复连接。

2、重发机制,每一条MT消息在发送后,等待60S后还未收到响应,应再次提交发送,发送3(可配置)次后均未收到响应,可视为链路中断,恢复链路连接,并重新提交MT消息,MT消息不能抛弃。如链路正常可把MT消息滞后发送。

3、心跳连接机制,为每个TCP连接,要建立心跳线程,一般采用60s-100s,在无MT消息后启用心跳线程来维持链路连接,连续2次心跳后均无应答应恢复链路连接。

4、CMPP滑动窗口限制,单次并发量限制在16条,待应答完毕后,再次并发。

5、数据缓存问题,网关发送的MT消息,存放在缓存中,对缓存大小要做严格的限制,达到规定数值后,暂时阻塞获取MT消息。

6、长短信问题,网关必须要支持长短信(长短信如何实现将在后期讲解)。

7、重复数据问题,运营商网关提交过来的数据可能会产生重复数据,因此重复数据必须抛弃;

8、排序机制,先到先发机制,保证数据的有序性。

消息头协议包定义

首先我们定义消息头协议包。

消息头包括Total_Length :消息总长度(4)Command_Id:类型(4)Sequence_Id:消息流水号(4)

总长度为4+4+4=12

MobileMessageTitle.cs

/// <summary>
/// 拆分消息头
/// </summary>
/// <param name="sb"></param>
public MobileMessageTitle(byte[] sb)
{
FromBytes(sb);
}

public MobileMessageTitle()
{
}

/// <summary>
/// 命令或响应类型
/// </summary>
private uint commandID;
/// <summary>
/// 命令或响应类型
/// </summary>
public uint CommandID
{
get
{
return this.commandID;
}
set
{
this.commandID = value;
}
}

/// <summary>
/// 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)
/// </summary>
private uint sequenceID;
/// <summary>
/// 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)
/// </summary>
public uint SequenceID
{
get
{
return this.sequenceID;
}
set
{
this.sequenceID = value;
}
}

/// <summary>
/// 消息头总长度 4+4+4=12
/// </summary>
public uint MessageTitleLength
{
get
{
return (4 + 4 + 4);
}
}

/// <summary>
/// 消息体长度
/// </summary>
private uint messageContentLength;
/// <summary>
/// 消息体长度
/// </summary>
public uint MessageContentLength
{
get
{
return this.messageContentLength;
}
set
{
this.messageContentLength = value;
}
}

/// <summary>
/// 消息头+消息体长度
/// </summary>
public uint MessageLength
{
get
{
return this.MessageContentLength + this.MessageTitleLength;
}

}

/// <summary>
/// 组合消息头
/// </summary>
/// <returns></returns>
public byte[] ToBytes()
{
byte[] rb = new byte[this.MessageTitleLength];
int index = 0;
Array.Copy(Tools.IntChangeNetByte(Tools.UintToUintArray(this.MessageLength)), 0, rb, index, 4);
index += 4;
Array.Copy(Tools.IntChangeNetByte(Tools.UintToUintArray(this.CommandID)), 0, rb, index, 4);
index += 4;
Array.Copy(Tools.IntChangeNetByte(Tools.UintToUintArray(this.SequenceID)), 0, rb, index, 4);
return rb;
}

/// <summary>
/// 拆分消息头
/// </summary>
/// <param name="sb"></param>
public void FromBytes(byte[] sb)
{

byte[] tsb = new byte[this.MessageTitleLength];
Array.Copy(sb, 0, tsb, 0, this.MessageTitleLength);
int index = 0;
this.MessageContentLength = Tools.UintArrayToUint(Tools.IntChangeNetByte(Tools.SubByte(tsb, index, 4))) - this.MessageTitleLength;
index += 4;
this.CommandID = Tools.UintArrayToUint(Tools.IntChangeNetByte(Tools.SubByte(tsb, index, 4)));
index += 4;
this.SequenceID = Tools.UintArrayToUint(Tools.IntChangeNetByte(Tools.SubByte(tsb, index, 4)));

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: