中文短信之希望
手机短信的发送接收原理与代码
; Y$ h3 V8 x# A# {4 x- i: L, a/ E! C" O* V0 k
中文转换成Unicode码函数; F- j8 P/ ~5 |7 [) i! d; f& K
% x* {' \) v: h4 Z, g
因为手机短消息的发送是以PDU串的形式发送出去的,中文字符以Unicode码来表示,所以在发送中文短消息之前必须首先将中文字符转换为Unicode码,下面的函数将实现这个功能。这个函数主要应用到VB自带的一个格式转换函数:ChrW()将中文转换为Unicode码。
3 ^/ p! m( c$ w
" v2 l, f0 p1 g- d1 Z* CPublic Function chg(rmsg As String) As String
7 {2 d0 }( {$ [Dim tep As String3 W: t/ r6 h! U+ o. Y- j+ J' p
Dim temp As String1 |, }% }6 S1 L1 X6 \) `
Dim i As Integer0 h$ T& g' n/ H' N2 ~
Dim b As Integer
0 C% [9 `5 H, J' ]5 Step = rmsg$ \, ^, ^) H9 i' f
i = Len(tep)% B8 h: r; m% ?/ r
b = i / 4
1 v. E0 E1 x5 r/ L% q, I- d! G; qIf i = b * 4 Then7 `; i" ~0 f& s/ z( X1 R
b = b - 16 C% I4 @* u5 t4 ?1 C6 R( _, o$ F% u
tep = Left(tep, b * 4)3 ~- P- h) _+ f8 p0 Q! k, ]7 H" ~4 b
Else
) [7 M' U( J, p# S! j tep = Left(tep, b * 4)& N0 q0 ]0 m# f, e
End If+ ^1 V/ o4 J9 S. J! m6 j- t
chg = ""& _. D9 _ [+ q* N6 i- v& q
For i = 1 To b2 x! |" R8 I% v0 x7 a2 V
temp = "&H" & Mid(tep, (i - 1) * 4 + 1, 4)5 L; H1 g; _0 A
chg = chg & ChrW(CInt(Val(temp)))
3 N9 L1 ^3 m: S. Y0 }Next i
; Y0 b0 K" v9 m) V6 W: dEnd Function 1 l& d( E* o2 H/ `5 f: _& v3 o
8 U4 y7 e% B3 R8 X4 B) r z- e/ w" q+ y6 g
² 短信中心手机号码的PDU串转换函数9 T* S0 s( ?, {3 w2 k& ^) D+ X E
m1 M+ M9 |# s7 K$ o, T& S同上,为了发送以PDU模式发送短消息,必须将手机号码和对方手机号码也转换为PDU格式,下面的函数就是为了实现这种转换:
9 o0 F3 c0 C8 R. u ]. i
2 [$ {2 |$ u2 G5 m2 IPublic Function telc(num As String) As String/ L. O) B; E1 H
Dim tl As Integer
+ t, e+ x2 j% ]Dim ltem, rtem, ttem As String
8 F! Q+ Y" x. c6 A9 b: z( eDim ti As Integer
1 }1 B5 w% ?9 a. I, V5 wttem = ""
) L/ g9 q! W) }2 ]tl = Len(num)( X& Y) ~2 I: [3 [! p# l
If tl <> 11 And tl <> 13 Then0 k; e2 F9 t0 V6 y$ s* o" I0 J: I
MsgBox "wrong number." & tl4 R* g9 i0 N3 x9 t: V$ ^# l; h
Exit Function. ~" }) ?; ]" B, {" F$ o
End If* m9 v$ k* }! Q' d
If tl = 11 Then
8 ^' n' W$ P7 G l8 x* h tl = tl + 2
8 X0 {9 H& ^: M% r- n5 w num = "86" & num
3 A5 y. ?: a, _* ]4 U2 s! G IEnd If
, ], {8 {; B+ t4 U- b; oFor ti = 1 To tl Step 2
0 w# U3 y' ]" Qltem = Mid(num, ti, 1)
1 s! l) z* O# x3 Y9 y6 D# r7 y' R* Krtem = Mid(num, ti + 1, 1)5 M0 Z) m9 ], D' Z( x, c2 i( n
If ti = tl Then rtem = "F"/ l, Q3 Q; v5 Z. o) w3 q
ttem = ttem & rtem & ltem8 M1 j5 ~4 u: r+ Q( b+ {
Next ti6 H5 ?: `& L! M
telc = ttem! C V- m: E: a) [
End Function
2 L$ v$ I0 E/ `$ c$ z6 v, V/ O4 ~- M; B7 B7 D. h
3 X+ i W+ l" q. r0 |! ^
手机号码有两种表示方法:11位和13位(带国家码86),一般手机发送时都是以13位形式表示的,所以以上的函数还有一个功能是自动将11位格式手机号码转换为13位形式,然后再转换为PDU串。# `- \0 e8 C* A1 J1 n
% i0 k4 L) @9 m/ W, y# ?: i
² 手机短信的发送% ^8 F/ d1 x' }
( N1 |1 `( `1 v0 }
手机短信的发送主要借助于VB的Mscomm控件实现,关于Mscomm控件,前面的技术介绍部分有详细介绍。短信的发送是由AT+CMGS指令完成的,采用PDU模式发送,函数代码如下:
" G) C7 H7 K" ^7 p2 U% p& V) g# C! C8 t5 S
Const prex = "0891"
! o, w, C* |, d d: a6 k- cConst midx = "11000D91"
_: F* e8 t2 G+ o. P5 PConst sufx = "000800"
: S. _0 M4 u) D! _- h5 iPublic Function Sendsms(csca As String, num As String, msg As String) As _Boolean G" `2 u) H8 S7 ^
Dim pdu, psmsc, pnum, pmsg As String
+ n, v9 s9 i/ ]6 z( r8 e+ S Dim leng As String
" u4 O9 j/ C' ] Dim length As Integer& c' p, G0 R) ~2 u. T
length = Len(msg)
( Z7 K3 M! a; j. Y b( d length = 2 * length7 _/ Y9 M9 d- U. u# n7 ]- X% I
leng = Hex(length)
* a6 M m q+ z# R& F If length < 16 Then leng = "0" & leng* O9 o B$ P% C- A+ p, w" n
psmsc = Trim(telc(csca))
$ U1 S. @3 l2 F E1 z, Q pnum = Trim(telc(num))& y" e$ C- J3 z; ~/ z v* W @
pmsg = Trim(ascg(msg))
/ u; F* H S. Y2 I- Y. m pdu = prex & psmsc & midx & pnum & sufx & leng & pmsg
' S6 a5 Y" }( C% T+ ^& zsleep(1)
, e/ Q1 R3 R. D4 ? mobcomm.Output = "AT+CMGF=0" + vbCr
% ], ^7 T, ^; O8 D6 w& R( U1 C0 X mobcomm.Output = "AT+CMGS=" & Str(15 + length) + vbCr
$ d! \% F3 B" Y0 P4 ]5 W5 gmobcomm.Output = pdu & Chr$(26)
; \8 T2 Y; ]7 Q0 U8 F+ wsleep(1)
& R2 w' q) K5 R Sendsms = True
" ?% p* n/ K8 ~) e9 i" ?& i/ AEnd Function x* i$ x+ J% a, o, |. L
& }4 O. D: @0 ]- n7 G4 q' ], F: p/ C8 N
因为手机同一时间只能处理一件事情,因此这个函数只负责发送短信,关于短信发送成功与否以及阅读短信的部分集中在一起处理。判断手机短信发送成功与否主要由AT+CMGS命令执行以后的返回码来决定(可参见前文的AT指令介绍部分)。
8 u5 Z( p6 W. F$ D1 r0 m; j
% E; m3 a" C% d& @为了防止手机因过于繁忙而出错,这里采取了一定的方法让手机有充分的时间处理发送和接收及删除等操作。Sleep()函数正是为此而设计的,在发送及删除操作后都会让程序暂停一秒,这样就不至于使得手机过于繁忙。
% ^6 z, w$ \/ B u2 |& q手机短信的接收* U4 b! y: U8 w* R2 k6 ]
Unicode码解码函数
/ y# I* Q; t1 q% A1 c- u
6 B7 J# s/ o2 {+ H6 H; y相比于手机短信的发送而言,手机短信的接收主要的工作正好与之相反。手机短信的发送需要将待发送的短信内容转换为Unicode码,而短信的接收则需要将接收到的Unicode码转换成中文字符。下面的函数将实现解码功能。同手机短信发送的编码函数一样,这里也应用了一个VB内置的函数AscW()函数来将Unicode码转换为中文:
( X, O- g. f% ^4 f+ ?# K6 Q
8 M9 D' r9 Y* H" G* |( qPublic Function ascg(smsg As String) As String
4 Z8 }2 [6 _" WDim si, sb As Integer
% ?5 t$ m! f9 i' U: Z; }Dim stmp As Integer
. H& k1 H- O6 s0 U# mDim stemp As String
& r: f3 o% b' M2 u7 vsb = Len(smsg)
1 ]9 [% a1 e& M5 M5 O( tascg = "" + n% B1 S* n. x6 p2 ]9 L9 O
For si = 1 To sb ' d+ A) e; `) D' e
stmp = AscW(Mid(smsg, si, 1)) 3 P( r' L# `4 ]) x4 k) y
If Abs(stmp) < 127 Then
6 b7 p( Q$ N% Mstemp = "00" & Hex(stmp) - ?1 X! h0 l' D4 C5 k$ g1 _9 j
Else
% o3 H: M S& H) m4 X; B; Hstemp = Hex(stmp) ; b: Y+ I+ H' f, L9 ~
End If
) e1 Y* }/ Q) B' F% N6 K7 c. [4 aascg = ascg & stemp 9 q2 q6 T0 q# @8 H4 E
Next si 8 k* X# w! H# H, }
ascg = Trim(ascg) 6 `5 Y9 `. r+ U9 @% Y
End Function
- _& w3 n2 i! e9 i' E' B/ j7 v
0 m* {% S; D/ \. o7 g
5 p# i# j+ \9 k1 p7 B* ]² 手机短信接收函数
) c1 L G% t! i: ^4 p* s3 i: F3 r$ r: B: m' ~& z1 E4 `; R K
相对于短信的发送函数而言,短信的接收相当简单,只需要以下的三行代码就完成了。但是它使用的技术却决不比短信的发送少,这里主要用到了Mscomm控件的Output属性和AT+CMGR指令。
5 a! O9 W8 \0 T" W7 V2 O: w1 f) Y( B) z4 V1 l4 a# Q
Public Sub readsms(rnum As String) F, U$ L( D3 r" n$ R4 A
mobcomm.Output = "AT+CMGF=1" + vbCr
) Z: R) y/ A8 m J. N0 Bmobcomm.Output = "AT+CMGR=" & rnum + vbCr . z7 C( F Q5 {6 d- v, ]9 ^5 _
End Sub