您的位置:首页 > 其它

思华CP接口协议 Socket包定义

2007-07-26 11:32 330 查看
[b]
思华CP接口Socket协议
[/b]
2007-6-20
1. 首先需要确认你拿到的是这个版本的协议,其它版本我不敢保证能行.

2. 思华定义的socket发送包我是头是遇到,搞不懂怎么回事,调试了三天,终于弄明白他是啥意思

3. Head 1字节 (Byte类型), Len 2字节 (Int16、Short类型,具体看语言决定,我这里列举的是.Net和VB里的), Context 具本看办议规定

4. 我用VB.Net 2.0开发,将上面的定义写成结构,再将结构转成Byte数组,现在网上有.Net下的转换函数(Struct2Bytes),可以自己搜一下,CSDN里也有。现在我们来看看.Net下对思华登录结构的定义:

#Region "定义登录"
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure Login
Public Head As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public Len() As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
Public Account() As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public Password() As Byte
End Structure
#End Region

这里有个问题。 Head 是Byte类型的,在转换后必须还是Byte类型,而且是一字节。比如说Head=1 那么Socket的发送Buff头一字节就是1, 而并不是ASCII码的49。

Len就更奇怪了。在Socket的发送Buff里占索引号的1 2位(也就是两字节)。 如果你直接把Len声明为Int16、Short或其它两字节的整型话,经结构转为Byte数组的结果是三位。比如Len=60,Buff看到的就是 0 60 0,那么登录的发送Buff那就是

1
0
60
0
X
X
X
X

这样的话传过去就不对,而且最明显的就是调用同步Socket的Send方法是会阻塞几秒钟,如要按正确的方式发送不会造成阻塞,我想他那边应该是异步接收。这就奇怪了,.Net 和 VC写的结构转成Buff都是这样,那么很明显就是写协议的人规定有问题,这里我不禁要狠狠B4一下。

所以我上面在登录结构中定义的Len写的是二字节的Byte,因为这里需要手动转换。而且转换还必须是高低位相反,简直没搞懂。比如 Len = 60那么Buff里就应该是
1
60
0

一般的程序处理出来应该是
1
0
60

这就太扯巴子了,所以我用了VB里的特有的Redim语法转换一下

Dim Len() As Byte

Len = System.Text.Encoding.ASCII.GetBytes(Chr(60))

Redim Preserve Len(1)

这时Len(0) = 60, Len(1)=0

其实也不用这么麻烦,因为结构发送一般都是定长,所以你也可以直接给Len数组赋值。

但如果长度超出128的话也会有问题,所以就以满256进1的原则来手动算吧,反正他定长,一般不会变。

比如发送短信的包是550,那么长度应该是

Len(0) = 38
Len(1) = 2

256*2+38=550,清楚了吗。2就是Len(1)里的

接下来就是Context,这个比较简单,转化为一般的ASCII数组就行
System.Text.Encoding.ASCII.GetBytes("思华写的很laji")。

接收思华主控发往CP的时候。

Context可以用Char()来替代,这样省去一道自行将Byte()转为String的工序

我的接收登录响应的结构定义

#Region "定义登录响应"
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Ansi)> _
Public Structure LoginReq
<FieldOffset(0)> Public Head As Byte
<FieldOffset(1)> Public Len As Int16
<FieldOffset(3)> Public Context As Char
End Structure
#End Region

'----------------------------

以下附上我的一个封装结构定义类 .Net 2.0的

(MsgStructure.vb)

Imports System.Runtime.InteropServices

#Region "定义登录"
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure Login
Public Head As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public Len() As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
Public Account() As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public Password() As Byte
End Structure
#End Region

#Region "定义登录响应"
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Ansi)> _
Public Structure LoginReq
<FieldOffset(0)> Public Head As Byte
<FieldOffset(1)> Public Len As Int16
<FieldOffset(3)> Public Context As Char
End Structure
#End Region

#Region "定义下行结构"
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure Send
Public Head As Byte

<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public Len() As Byte

Public Context As SendContext
End Structure
#End Region

#Region "定义下行内容体"
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure SendContext

'(移动CMPP,电信SMGP,联通SGIP,网通SNGP)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
Public MsgKind() As Byte

'内部信息标识
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public LinkNo() As Byte

'相同Msg_Id的信息总条数,默认为1
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public PkTotal() As Byte

'相同Msg_Id的信息序号,默认为1
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public PkNumber() As Byte

'计费用户类型
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public FeeUserType() As Byte

'业务代码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
Public ServiceCode() As Byte

'计费类型
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public FeeType() As Byte

'费用代码(1元用100表示)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public FeeCode() As Byte

'包月费/封顶费
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public FixedFee() As Byte

'赠送费用
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public GivenValue() As Byte

'收费用户号码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)> _
Public FeeTerminalID() As Byte

'收费用户号码类型,默认为0
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public FeeTerminalIDType() As Byte

'信息格式 (15代表包含汉字,一般用15)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public MsgFmt() As Byte

'内部的有效期时间 (过期时间)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=19)> _
Public ValidTime() As Byte

'内部的执行时间 (定时发送)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=19)> _
Public AtTime() As Byte

'发送号码(此处为SP的端口+长号码)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=21)> _
Public SrcID() As Byte

'接收号码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)> _
Public DestID() As Byte

'接收号码类型, 收费用户号码类型(0真实号码,1伪码)默认为0
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public DestIDType() As Byte

'信息内容
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=255)> _
Public MsgContent() As Byte

'上行信息的LINKID,无上行不填
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public LinkID() As Byte

'短信类型
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public MsgType() As Byte

'SP代码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
Public SPCode() As Byte

'ServiceID
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
Public ServiceID() As Byte
End Structure
#End Region

#Region "定义上行内容体"
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure ReceiveUpContext

'内部信息标识
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public LinkNo() As Char

'MsgID
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public MsgID() As Char

'接收号码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=21)> _
Public DestID() As Char

'接收号码类型(0、真实号码,1、伪码)
Public DestIDType As Char

'发送号码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)> _
Public SrcID() As Char

'发送号码类型(0、真实号码,1、伪码)
Public SrcIDType As Char

'业务代码
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public ServiceCode() As Char

'信息格式 (15代表包含汉字)
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public MsgFmt() As Char

'信息内容
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=255)> _
Public MsgContent() As Char

'点播业务使用的LinkID,非点播类业务的MT流程不使用该字段
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=50)> _
Public LinkID() As Char
End Structure
#End Region

#Region "心跳下行结构"
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure HeartJump
Public Head As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
Public Len() As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public Context() As Byte
End Structure
#End Region
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: