WaveCom 短信猫C#开发,有问题的进来讨论下----(先占个位子)

news/2024/7/7 12:53:25

悲剧了那,呵呵。这边http://www.cnblogs.com/engin/archive/2010/11/23/1885907.html有个具体的,我这个就当自己做过写点感触了。

最近在开发应用级的短信发送东东。不说别的了,下面就是咱的家伙:

     短信猫为:USB wavecom Q2406A的GSM(据说GSM的只能发短信,Gprs的能发短信也猛发彩信)短信猫。

按照卖家给的说明书和网上搜集来的资料,在自己的百般(也许没这么多)下终于发出了第一条短信:

     第一条短信是利用微软的超级终端(在开始->程序->附件->通讯里面的)连接短信猫,然后使用at指令进行的短信文本格式发送。

at命令:

        atz 初始化短信猫

        at + cmgf=1  选择文本格式发送短信,注意,文本格式下发送短信只能发送abcd的字母。

        at + cmgs=13469273621  接收短信的人的号码,

       >    输入字母内容,输入后不要回车 直接按住Ctrl + Z组合键 就可以发送了

--------------------------------------------------------------------------------------------------------------------------------------

   但是,真正的应用去需要发送中文。而且还遇到了长、短短信的问题。即汉字输入下的七十个字符算作一条短信。七十个字以内的短信可以做一条发送,

接收者看到的也是一条短信。如果,字符量超过了七十个那就要自己分条发送了。但这是就出现了一个最优的要求:分条可以,但是我总得可以让接收者

当作一条看吧。不用看完一条再看一条,有时候还会因为断章取义出现误会。这时候,我只找到了一种答案:使用PDU编码发送短信。

    一、发送短短信。

相关文章链接:

                有点儿关于超级终端使用的东西

                 http://www.ccidcom.com/blog/?uid-11541-action-viewspace-itemid-52809

                讲解PDU编码协议的

                 http://blog.21ic.com/user1/4641/archives/2008/45476.html

超级终端在这里

%E8%B6%85%E7%BA%A7%E7%BB%88%E7%AB%AF.JPG

%E8%B6%85%E7%BA%A7%E7%BB%88%E7%AB%AF-%E8%BF%90%E8%A1%8C.jpg

点确定后
%E8%B6%85%E7%BA%A7%E7%BB%88%E7%AB%AF--%E9%80%89%E6%8B%A9.jpg

选择你的短信猫使用的端口
%E8%B6%85%E7%BA%A7%E7%BB%88%E7%AB%AF--%E5%88%9D%E5%A7%8B.jpg
点还原为默认后
%E8%B6%85%E7%BA%A7%E7%BB%88%E7%AB%AF--%E9%BB%98%E8%AE%A4.jpg

确定后就可以使用了



使用PDU编码发送长短短信017.gif

      短信猫的操作命令为 
            AT + CMGF=0
            AT+CMGS=发送内容长度
            >内容Ctrl+Z发送

        将一条短信所有内容进行PDU编码的代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;

namespace SMS.Service
{

      
/// <summary>
      
/// 针对国内短信编码(USC2)
      
/// </summary>
    public class PDUdecoding
    {
        
public readonly static int MAX_CHAR_COUNT = 70;//最长可发送汉字个数

        
/// <summary>
        
/// 获取单条短信最大发送字符个数
        
/// </summary>
        
/// <returns></returns>
        public static int GetMaxEncodeCharCount()
        {
            
return PDUdecoding.MAX_CHAR_COUNT * 2 - 6;
        }

        
/// <summary>
        
/// 短信内容编码
        
/// </summary>
        
/// <param name="value"></param>
        
/// <returns></returns>
        
/// <remarks>
        
/// 采用Big-Endian 字节顺序的 Unicode 格式编码,将高低位互换
        
/// 将转换后的短信内容存进字节数组
        
/// 去掉在进行Unicode格式编码中,两个字节中的"-",例如:00-21,变成0021
        
/// 将整条短信内容的长度除2,保留两位16进制数
        
/// </remarks>
        public static string Encoding(string value)
        {
            Encoding encoding 
= System.Text.Encoding.BigEndianUnicode;
            
string result = string.Empty;
            
byte[] bytes = encoding.GetBytes(value);

            
for (int i = 0; i < bytes.Length; i++)
            {
                result 
+= BitConverter.ToString(bytes, i, 1);
            }

            
return result;
        }

        
/// <summary>
        
/// 奇偶互换并补F
        
/// </summary>
        
/// <param name="value"></param>
        
/// <returns></returns>
        private static string ParityChange(string value)
        {
            
string result = string.Empty;
            
int length = value.Length;
            
for (int i = 1; i < length; i += 2)//奇偶互换
            {
                result 
+= value[i];
                result 
+= value[i - 1];
            }

            
if (!(length % 2 == 0))//不是偶数则加上F,与最后一位互换
            {
                result 
+= 'F';
                result 
+= value[length - 1];
            }
            
return result;
        } 
        

        
/// <summary>
        
/// 接收短信手机号码编码
        
/// </summary>
        
/// <param name="phone"></param>
        
/// <returns></returns>
        public static string DecodingPhone(string phone)
        {
            
string result = string.Empty;

            
if (null == phone || 0 == phone.Length)
            {
                
return result;
            }

            
if ('+' == phone[0])
            {
                phone 
= phone.TrimStart('+');
            }

            
if (!(phone.Substring(02== "86"))//补86
            {
                phone 
= String.Format("86{0}", phone);
            }

            
return ParityChange(phone);
        }

        
#region  尚不使用 
        
/// <summary>
        
/// 短信中心号码编码
        
/// </summary>
        
/// <param name="value"></param>
        
/// <returns></returns>
        public static string DecodingCenter(string phone)
        {
            
string result = string.Empty;
            result 
= ParityChange(phone);

            result 
= String.Format("91{0}", result);//加上91
            result = String.Format("{0:X2}{1}", result.Length / 2, result);
            
return result;
        }

        
#endregion

        
/// <summary>
        
/// 编码短信的发送内容
        
/// </summary>
        
/// <param name="content">短信的发送内容</param>
        
/// <returns></returns>
        public static string EncodingContent(string content)
        {
            
string result = string.Empty;
            
byte[] bytes = System.Text.Encoding.BigEndianUnicode.GetBytes(content);

            
//for (int i = 0; i < bytes.Length; i++)
            
//{
            
//    if (0x80 == (bytes[i] & 0x80))//汉字 6c49  108 73
            
//    {
            
//        result = string.Format("{0}{1:X2}", result, bytes[i]);
            
//        result = string.Format("{0}{1:X2}", result, bytes[++i]);
            
//    }
            
//    else
            
//    {
            
//        result = string.Format("{0}00{1:X2}", result, bytes[i]);
            
//    }
            
//}
            foreach (char item in content)
            {
                bytes 
= System.Text.Encoding.BigEndianUnicode.GetBytes(new char[1] { item });
                
if (bytes.Length < 2)
                    
continue;

                
//
                if (0x80 == (Asc(item) & 0x80))//汉字
                {
                    result 
= string.Format("{0}{1:X2}", result, bytes[0]);
                    result 
= string.Format("{0}{1:X2}", result, bytes[1]);
                }
                
else
                {
                    result 
= string.Format("{0}00{1:X2}", result, bytes[1]);
                }
            }
            
return result;
        }
        
        
        
/// <summary>
        
/// 将发送内容同时在前面补上短信内容长度进行编码,
        
/// </summary>
        
/// <param name="value"></param>
        
/// <returns></returns>
        public static string EncodeingAddLength(string value)
        {
            
//对短信内容进行编码 
            string result = Encoding(value);

            
//补上内容长度 ,组合。
            return String.Format("{0:X2}{1}", result.Length / 2, result);
        }


        
/// <summary>
        
/// 短短信的PDU编码
        
/// </summary>
        
/// <param name="center">短信中心号码</param>
        
/// <param name="phone">接收者手机号码</param>
        
/// <param name="content">发送内容</param>
        
/// <param name="length">要发送内容的长度,由两部分组成,接收手机号加上要发送的内容</param>
        
/// <returns>编码</returns>
        public static string EncodingSMS(string center, string phone, string content, out string length)
        {
            
//center = DecodingCenter(center);

            
string result = String.Format("{0}11000D91{1}000800{2}", center, DecodingPhone(phone), EncodeingAddLength(content));

            length 
= String.Format("{0:D2}", result.Length / 2 - center.Length / 2);//获取发送编码的长度==计算除去短信服务中心号码后的编码长度 除以 二

            
return result;
        }


        
///<summary>
        
/// 发送超长短信
        
/// </summary>
        
/// <param name="center">短信中心号码</param>
        
/// <param name="phone">接收者号码</param>
        
/// <param name="count">短信分条总数</param>
        
/// <param name="index">短信分条索引</param>
        
/// <param name="content">已编码短信内容</param>
        
/// <param name="length">当前分条的长度</param>
        
/// <returns>当前分条短信的内容</returns>
        public static string EncodingSMS(string center, string phone, int count, int index, string content, out string length)
        {
            content 
= EncodingContent(content);
            
string message = string.Empty;
            
int msgcount = PDUdecoding.GetMaxEncodeCharCount() * 2;//固定

            
if (index == count)
            {
                message 
= content.Substring((index - 1* msgcount); //共可发送134个编码
            }
            
else
            {
                message 
= content.Substring((index - 1* msgcount, msgcount);
            }

            
//加密消息中心号码
            
//center = DecodingCenter(center);

            
//string result = string.Format("005100{0}{1}0008A7{2:X2}05000304{3:D2}{4:D2}{5}",
            
//                            center,
            
//                            DecodingPhone(phone),
            
//                            (message.Length + 12) / 2,
            
//                            count,
            
//                            i,
            
//                            message);

            
//length = String.Format("{0:D2}", result.Length / 2 - center.Length / 2);//获取短信内容加上手机号码长度

            
/**/
            
////string ph = phone;
            
////phone = DecodingPhone(phone).Substring(2);

            
////string result = string.Format("005100{0}{1}0008A7{2:X2}05000304{3:D2}{4:D2}{5}",
            
////                              string.Format("{0:X2}A1", ph.Length),
            
////                            phone,
            
////                            (message.Length + 12) / 2,
            
////                            count,
            
////                            i,
            
////                            message);

            
string result = String.Format("{0}51000D91{1}000800{2:X2}05000304{4:D2}{5:D2}{3}",
                                            center,
                                           DecodingPhone(phone),
                                           message.Length 
/ 2 + 6,
                                            message,
                                            count,
                                         index
                                            );

            length 
= String.Format("{0:D2}", result.Length / 2 - center.Length / 2);//获取短信内容加上手机号码长度

            
return result;
        }

        
#region 不能正常使用
        
/// <summary>
        
/// 超长短信
        
/// </summary>
        
/// <param name="center">短信息中心号码</param>
        
/// <param name="phone">接收者手机号码</param>
        
/// <param name="content">消息内容</param>
        
/// <param name="count">消息分条总数量</param>
        
/// <param name="index">获取第几条分条</param>
        
/// <param name="length">当前分条长度</param>
        
/// <returns>当前消息分条内容</returns>
        //public static string EncodingSMS(string center, string phone, string content, int count, int index, out string length)
        
//{
        
//    if (content.Length <= PDUdecoding.MAX_CHAR_COUNT)
        
//    {
        
//        return PDUdecoding.EncodingSMS(center, phone, content, out length);
        
//    }
        
//    else
        
//    {
        
//        if (count - 1 == index)
        
//        {
        
//            content = content.Substring(index * (PDUdecoding.MAX_CHAR_COUNT - 6));
        
//        }
        
//        else
        
//        {
        
//            content = content.Substring(index * (PDUdecoding.MAX_CHAR_COUNT - 6), PDUdecoding.MAX_CHAR_COUNT - 6);
        
//        }

        
//        center = DecodingCenter(center);
        
//        content = Encoding(content);

        
//        string result = "";

        
//        DateTime tm = DateTime.Now;

        
//        //result = string.Format("{0}44000D91{1}0008{2}{3:X2}05000304{4:D2}{5:D2}{6}",
        
//        //                        center,
        
//        //                        DecodingPhone(phone),
        
//        //                        ParityChange(string.Format("{0:X2}{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}08", tm.Year - 2000, tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second)),
        
//        //                        (content.Length + 12) / 2,
        
//        //                        count,
        
//        //                        i + 1,
        
//        //                        content
        
//        //                        );

        
//        result = string.Format("005100{0}{1}0008A7{2:X2}05000304{3:D2}{4:D2}{5}",
        
//                                center,
        
//                                DecodingPhone(phone),
        
//                                (content.Length + 12) / 2,
        
//                                count,
        
//                                index + 1,
        
//                                content);

        
//        length = String.Format("{0:D2}", result.Length / 2 - center.Length / 2);//获取短信内容加上手机号码长度
        
//        return result;
        
//    }
        
//}
        #endregion

        
private static int Asc(char item)
        {
            
byte[] bytes = System.Text.Encoding.Default.GetBytes(new char[1] { item });
            
if (bytes.Length < 2)
                
return bytes[0];

            
return bytes[0* 256 + bytes[1- 65535;
        }
    }

}


用C#中的SerialPort 进行COM端口操作


ContractedBlock.gif ExpandedBlockStart.gif Code
#region


        
/// <summary>
        
/// 发送短信(长/短)
        
/// </summary>
        
/// <param name="sp">GSM短信猫SerialPort端口对象</param>
        
/// <param name="serviceCenterAddress">短信中心号码</param>
        
/// <param name="text">内容</param>
        
/// <param name="phonenumber">接收者号码</param>
        
/// <param name="count">短信分条总量</param>
        
/// <param name="index">当前第几条</param>
        public static void GSMModemSMSsend(
            SerialPort sp,
            
string serviceCenterAddress,
            
string text,
            
string phonenumber,
            
int count,
            
int index
            )
        {
            
try
            {
                
if (sp.IsOpen)
                {
                    sp.Close();
                }
                sp.Open();


                
string length = "";

                
if (count == 1)
                {
                    
string smsTemp = PDUdecoding.EncodingSMS("00", phonenumber, text, out length);

                    
#region Short SMS Send

                    sp.WriteLine(
"atz"); //短信猫初始化命令
                    sp.WriteLine("at + cmgf=0");  //以PDU编码格式发送短信

                    sp.WriteLine(String.Format(
"at + cmgs={0}", length)); //设置通信内容长度
                    sp.Write(smsTemp);  //写入PDU编码的通信内容

                    sp.WriteLine(
"\x01a");  //Ctrl + Z 发送短信

                    
#endregion
                }
                
else
                {
                    
#region Long SMS Send

                    
string smsTemp = PDUdecoding.EncodingSMS(serviceCenterAddress, phonenumber, count, index, text, out length);

                    sp.WriteLine(
"atz"); //短信猫初始化命令
                    sp.WriteLine("at + cmgf=0"); //以PDU编码格式发送短信

                    sp.WriteLine(String.Format(
"at + cmgs={0}", length));  //设置通信内容长度

                    sp.Write(smsTemp);  
//写入PDU编码的通信内容

                    sp.WriteLine(
"\x01a"); //Ctrl + Z 发送短信


                    
#endregion
                }

            }
            
catch (Exception ex)
            {
                
throw ex;
            }
            
#region 获取端口的命令写入写出部分情况  调试时使用

            
//byte[] buffer = new byte[sp.ReadBufferSize];
            
//sp.Read(buffer, 0, buffer.Length);
            
//string response = Encoding.ASCII.GetString(buffer);

            
#endregion




        }
        
#endregion



001.gif 第一次写出来时 短信猫发送短信的时间间隔竟然是二十秒左右,不然会出现部分文字丢失的情况。老板相当不能容忍,于是又翻回来左看右看
终于发现点还算有价值的东西,现在写在这里为大家参考。
      第一,使用PDU编码发送短信 正常长度为151
                  为什么说是正常长度? 这个正常长度指的是出去在短信PDU通信协议中的其他固定成分外的用户内容的大小。注意:太大的长度则会产生
                   较长的发送时间。
      第二、我得出的短信发送时间间隔值
                  PDU编码长度为17或21(短短信一个字,长短信一个字)的发送时间间隔为5秒
                  长度为151的发送时间间隔为 8.5秒

所以,上面的代码还是要进行修改的

转载于:https://www.cnblogs.com/klvk/archive/2009/08/31/1557458.html


http://www.niftyadmin.cn/n/3613225.html

相关文章

旋转矩阵求解欧拉角Python实现

旋转矩阵求解欧拉角Python实现基本知识绕静系与动系旋转静系动系与左乘右乘旋转矩阵连乘的两种理解文件目录实现方式使用矩阵方程手动求解SCIPY库求解在线计算网站总结笔者在外实习过程中&#xff0c;发现公司使用的不同的工业机器人默认欧拉角顺规有所不同&#xff0c;应部门组…

Simulink中FromWorkspace模块的使用

目录通过结构体的方式加载数据具体步骤注意事项通过结构体的方式加载数据 具体步骤 设&#xff0c; 有时间序列&#xff08;列向量&#xff09;[TimeValues]&#xff0c; 有数据序列&#xff08;矩阵&#xff0c;每组数据为一列向量&#xff09;[DataValues] [DataValues1, …

MathType的标尺栏与公式对齐

目录MathType的标尺栏插入/编辑/删除制表符使用标尺栏对齐公式笔者在撰写毕业论文时&#xff0c;使用到了MathType软件编写公式&#xff0c;下面是关于标尺栏的应用记录。 MathType的标尺栏 MathType的标尺栏由标尺和快捷制表符工具&#xff08;笔者随便起的名……&#xff0…

android深入研究和学习的课程

Android是Google基于Linux开发的智能手机操作系统&#xff0c;广泛应用于3G手机、上网本等。目前处于爆发式增长阶段&#xff0c;HTC(宏达电 多普达)、摩托罗拉、索爱、三星等众多公司纷纷推出基于Android智能操作系统&#xff0c;甚至很多上网本也使用Android操作系统。目前An…

2021航天招聘

2021航天招聘航天科技一院总体设计部15所18所航天科工二院未来实验室二部&#xff08;北京电子工程总体研究所&#xff09;23所&#xff08;北京无线电测量研究所&#xff09;25所&#xff08;北京遥感设备研究所&#xff09;201所&#xff08;防御技术研究实验中心&#xff09…

一个开源的flash幻灯片展示源码文件

来自于:http://www.jeroenwijering.com/基本效果如上图.采 用flashXML制作的幻灯切换效果。很多地方都可以用到。本代码只能使用标准的jpg格式,其他格式图片无法显示&#xff0e;需插入网页中观看效果使用&#xff0c;直接 打开swf文件无法看到其效果&#xff0e;页面中使用时可…

嵌入式Linux系统中的快速启动技术研究

摘要 Linux在消费电子类产品中得到了广泛应用&#xff0c;由于嵌入式用户对于系统启动速度较为敏感&#xff0c;因此快速启动技术逐渐成为研究和应用中的一个重点。本文通过对嵌 入式 Linux的启动时序和主要延时因素的分析&#xff0c;针对性地探讨了在各个启动阶段降低时耗的技…

万能清除浮动样式

这个是一个很流行的清除浮动的方法&#xff0c;在很多大项目上已经被完全采用。这个方法来源于positioniseverything &#xff0c;通过after伪类:after和IEhack来实现&#xff0c;完全兼容当前主流浏览器。 <style type"text/css"> .clearfix:after { content:…