一般短信都是140个字节,即70汉字。如果发送超过140字节的信息,一种是告诉运营商这条是长短信,那么服务中心就会自动的拆分重组。我用的工业级短信模块,不支持长短信,只有自己拆分,重组了。我现在的思路是将长短信拆分后加上特定的标识符,然后接收端根据标识符重组(我发送的长短信,只有我自己编写的软件接收)
初步想法标识符是给信息加上时间戳,同时加上信息总数是几个这是第几个,再加上发送方的号码。
不过现在脑子比较乱,想了一天了,具体实现也遇到很多困难,请大家给指点指点迷津

解决方案 »

  1.   

    我也做过,不过没你这么复杂直接截取后存到数据库,然后通过别的扫描程序进行发送,发送的时候采用asc读取表信息,如果desc那就倒着发了 呵呵   没想太多,简简单单的
      

  2.   

    长短信是有规约的,协议头部分如果是0x40以下,则说明是普通短信,如果是0x40以上,则是长短信,然后在短信内容部分,有六个字节分别定义短信唯一标识以及该短信是第几条,所以长短信发送时每条实际为67个汉字。手机接收到之后,都会按照标准规约自动组合为一条短信,而不是显示多条。
    我做了一个AT指令操作wavecom短信猫的类,可以接收和发送超长短信,并且接收到的短信会直接通知电脑。    class DuanXin
        {
            public string phnum;
            public string message;
            public DuanXin()
            {        }
            public DuanXin(string ph, string msg)
            {
                phnum = ph;
                message = msg;
            }
        }
        class CDuanXin
        {
            public byte biaozhi;
            public byte tiaoshu;
            public byte dqtiaoshu;
            public string dianhua;
            public string msg;
            public DateTime datetime;
            public CDuanXin(byte bz, byte ts, byte dqts, string dh, string mg, DateTime dt)
            {
                biaozhi = bz;
                tiaoshu = ts;
                dqtiaoshu = dqts;
                dianhua = dh;
                msg = mg;
                datetime = dt;
            }
        }
        public class WaveComMsg
        {
            public int Port;
            public int error;
            readonly string zhongzhi = new string((char)26, 1);
            const string head = "00";
            const string quyu = "000D9168";
            const string bianma = "000801";
            const string shujutou = "050003";
            const string ddx = "11";
            const string cdx = "55";
            StringBuilder fszifu = new StringBuilder(350);
            Queue<DuanXin> duanxins = new Queue<DuanXin>(60);
            Object listobj = new Object();
            List<string> items = new List<string>(8);
            public Action<int, string, string, int> Fsjieguo = null;
            public Action<string, string, DateTime> RcvMsg = null;
            public Action DuQu = null;
            bool kongxian = true;
            bool duqu = true;
            Action<DuanXin> Sendmsg = null;
            Random rd = new Random();
            SerialPort sp = null;
            List<CDuanXin> recvcd = new List<CDuanXin>(20);
            public WaveComMsg(int port)
            {
                Port = port;
                sp = new SerialPort("COM"+port);
                sp.RtsEnable = true;
                sp.DtrEnable = true;
                DuQu = ksduqu;
                sp.Open();
                Sendmsg = sendmessage;
            }
            public bool Chushihua()
            {
                string ss = string.Empty;
                try
                {
                    sp.Write("AT+CMGF=0" + "\r");
                    while (true)
                    {
                        ss = sp.ReadLine();
                        if (ss.Contains("OK"))
                            break;
                        else if (ss.Contains("ERROR"))
                            return false;
                    }
                }
                catch
                {
                    return false;
                }
                try
                {
                    sp.Write("AT+CNMI=2,2,0,0,1" + "\r");
                    while (true)
                    {
                        ss = sp.ReadLine();
                        if (ss.Contains("OK"))
                        {
                            sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
                            return true;
                        }
                        else if (ss.Contains("ERROR"))
                            return false;
                    }
                }
                catch
                {
                    return false;
                }
            }
            public void DoWork(string phnumber, string msg)
            {
                DuanXin dx = new DuanXin(phnumber, msg);
                bool busy = false;
                lock (listobj)
                {
                    if (duanxins.Count > 0)
                        busy = true;
                    duanxins.Enqueue(dx);
                }
                if (!busy)
                    Sendmsg.BeginInvoke(dx, null, null);
            }
            void sendmessage(DuanXin dx)
            {
                byte[] msgs = Encoding.BigEndianUnicode.GetBytes(dx.message);
                if (dx.message.Length <= 70)
                {
                    fszifu.Append(head);
                    fszifu.Append(ddx);
                    fszifu.Append(quyu);
                    fszifu.Append(phonedecode(dx.phnum));
                    fszifu.Append(bianma);
                    fszifu.Append(Convert.ToString((dx.message.Length) * 2, 16).PadLeft(2, '0'));
                    for (int i = 0; i < msgs.Length; i++)
                        fszifu.Append(Convert.ToString(msgs[i], 16).PadLeft(2, '0'));
                    fszifu.Append(zhongzhi);
                    items.Add(fszifu.ToString());
                    fszifu.Clear();
                }
                else
                {
                    string h = Convert.ToString(rd.Next(1, 127), 16);
                    int lnum = dx.message.Length / 67 + 1;
                    for (int i = 0; i < lnum; i++)
                    {
                        int sjl = i + 1 == lnum ? msgs.Length % 134 + 6 : 140;
                        fszifu.Append(head);
                        fszifu.Append(cdx);
                        fszifu.Append(quyu);
                        fszifu.Append(phonedecode(dx.phnum));
                        fszifu.Append(bianma);
                        fszifu.Append(Convert.ToString(sjl, 16).PadLeft(2, '0'));
                        fszifu.Append(shujutou);
                        fszifu.Append(h.PadLeft(2, '0'));
                        fszifu.Append(Convert.ToString(lnum, 16).PadLeft(2, '0'));
                        fszifu.Append(Convert.ToString(i + 1, 16).PadLeft(2, '0'));
                        for (int x = 0; x < sjl - 6; x++)
                            fszifu.Append(Convert.ToString(msgs[i * 134 + x], 16).PadLeft(2, '0'));
                        fszifu.Append(zhongzhi);
                        items.Add(fszifu.ToString());
                        fszifu.Clear();
                    }
                }
                string ss;
                int success = 0;
                kongxian = false;
                for (int m = 0; m < items.Count; m++)
                {
                    try
                    {
                        sp.Write("AT+CMGS=" + (items[m].Length / 2 - 1).ToString().PadLeft(3, '0') + "\r");
                        sp.Write(items[m]);
                        while (true)
                        {
                            ss = sp.ReadLine();
                            if (ss.StartsWith("0891"))
                                readmsg(ref ss);
                            else if (ss.Contains("OK"))
                            {
                                success = 1;
                                break;
                            }
                            else if (ss.Contains("ERROR"))
                            {
                                success = 0;
                                break;
                            }
                        }
                    }
                    catch
                    {
                        success = 0;
                    }
                }
                kongxian = true;
                if (success == 0)
                    error++;
                if (Fsjieguo != null)
                    Fsjieguo.BeginInvoke(Port, dx.phnum, dx.message, success, null, null);
                items.Clear();
                bool busy = false;
                lock (listobj)
                {
                    duanxins.Dequeue();
                    if (duanxins.Count > 0)
                        busy = true;
                }
                if (busy)
                    Sendmsg.BeginInvoke(duanxins.Peek(), null, null);
            }
            unsafe string phonedecode(string ph)
            {
                int x = ph.Length % 2 == 0 ? ph.Length : ph.Length + 1;
                char* ca = stackalloc char[x];
                for (int i = 0; i < x; i++)
                    if (i % 2 == 0)
                        *(ca + i) = (i + 1) == ph.Length ? 'F' : ph[i + 1];
                    else
                        *(ca + i) = ph[i - 1];
                return new string(ca, 0, x);
            }
            unsafe string phoneencode(string ph)
            {
                int x = ph.Length;
                char* ca = stackalloc char[x];
                for (int i = 0; i < x; i++)
                    if (i % 2 == 0)
                        *(ca + i) = ph[i + 1];
                    else
                        *(ca + i) = ph[i - 1];
                if (*(ca + x - 1) == 'F')
                    x--;
                return new string(ca, 0, x);
            }
            unsafe DateTime fsshijian(string sj)
            {
                DateTime dt = new DateTime();
                if (sj.Length == 10)
                {
                    char* ca = stackalloc char[16];
                    ca[0] = '2';
                    ca[1] = '0';
                    ca[2] = sj[1];
                    ca[3] = sj[0];
                    ca[4] = '/';
                    ca[5] = sj[3];
                    ca[6] = sj[2];
                    ca[7] = '/';
                    ca[8] = sj[5];
                    ca[9] = sj[4];
                    ca[10] = ' ';
                    ca[11] = sj[7];
                    ca[12] = sj[6];
                    ca[13] = ':';
                    ca[14] = sj[9];
                    ca[15] = sj[8];
                    DateTime.TryParse(new string(ca, 0, 16), out dt);
                }
                return dt;
            }
            unsafe void ksduqu()
            {
                bool ydx = false;
                string s = string.Empty;
                while (true)
                {
                    try
                    {
                        s = sp.ReadLine();
                    }
                    catch
                    {
                        ydx = false;
                        break;
                    }
                    if (s.StartsWith("0891"))
                    {
                        ydx = true;
                        break;
                    }
                }
                duqu = true;
                if (ydx)
                    readmsg(ref s);
            }
      

  3.   


            void readmsg(ref string s)
            {
                s = s.Trim();
                string mmsg = string.Empty;
                int cd = Convert.ToInt32(s.Substring(18, 2), 16);
                int hmcd = Convert.ToInt32(s.Substring(20, 2), 16);
                if (hmcd % 2 == 1)
                    hmcd++;
                string phonum = phoneencode(s.Substring(24, hmcd));
                string bm = s.Substring(24 + hmcd, 4);
                DateTime fssj = fsshijian(s.Substring(28 + hmcd, 10));
                int len = Convert.ToByte(s.Substring(42 + hmcd, 2), 16);
                if (cd < 64)
                {
                    byte[] b = new byte[len];
                    if (bm == "0000")//text
                    {
                        byte y = 0;
                        int l = 0;
                        for (int t = 0; t < len; t++)
                        {
                            if (t % 8 == 7)
                            {
                                l++;
                                b[t] = y;
                                y = 0;
                            }
                            else
                            {
                                byte x = Convert.ToByte(s.Substring(2 * (t - l) + 44 + hmcd, 2), 16);
                                b[t] = (byte)((((byte)(x << ((t - l) % 7) + 1)) >> 1) + y);
                                y = (byte)(x >> (7 - ((t - l) % 7)));
                            }
                        }
                        mmsg = Encoding.ASCII.GetString(b);
                    }
                    else if (bm == "0008")//tpdu
                    {
                        for (int i = 0; i < len; i++)
                            b[i] = Convert.ToByte(s.Substring(44 + hmcd + i * 2, 2), 16);
                        mmsg = Encoding.BigEndianUnicode.GetString(b);
                    }
                    if (RcvMsg != null)
                        RcvMsg.BeginInvoke(phonum, mmsg, fssj, null, null);
                }
                else
                {
                    byte[] b = new byte[len];
                    if (bm == "0000")//text
                    {
                        byte y = 0;
                        int l = 0;
                        for (int t = 0; t < len; t++)
                        {
                            if (t % 8 == 7)
                            {
                                l++;
                                b[t] = y;
                                y = 0;
                            }
                            else
                            {
                                byte x = Convert.ToByte(s.Substring(2 * (t - l) + 44 + hmcd, 2), 16);
                                b[t] = (byte)((((byte)(x << ((t - l) % 7) + 1)) >> 1) + y);
                                y = (byte)(x >> (7 - ((t - l) % 7)));
                            }
                        }
                        mmsg = Encoding.ASCII.GetString(b, 7, len - 7);
                    }
                    else if (bm == "0008")//tpdu
                    {
                        for (int i = 0; i < len - 6; i++)
                            b[i] = Convert.ToByte(s.Substring(56 + hmcd + i * 2, 2), 16);
                        mmsg = Encoding.BigEndianUnicode.GetString(b, 0, len - 6);
                    }
                    byte bz = Convert.ToByte(s.Substring(50 + hmcd, 2), 16);
                    byte ts = Convert.ToByte(s.Substring(52 + hmcd, 2), 16);
                    byte dqts = Convert.ToByte(s.Substring(54 + hmcd, 2), 16);
                    recvcd.Add(new CDuanXin(bz, ts, dqts, phonum, mmsg, DateTime.Now));
                    var cx = (from c in recvcd where c.biaozhi == bz && c.dianhua == phonum orderby c.dqtiaoshu select c).Distinct();
                    if (cx.Count() == ts)
                    {
                        string hjmsg = null;
                        foreach (var m in cx)
                        {
                            hjmsg += m.msg;
                            recvcd.Remove(m);
                        }
                        if (RcvMsg != null)
                            RcvMsg.BeginInvoke(phonum, hjmsg, fssj, null, null);
                    }
                    var ccx = from c in recvcd where (DateTime.Now - c.datetime).Minutes > 30 select c;
                    foreach (var n in ccx)
                        recvcd.Remove(n);
                }
            }
            void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                if (kongxian)
                {
                    if (duqu)
                    {
                        duqu = false;
                        DuQu.BeginInvoke(null, null);
                    }
                }
            }
            public void release()
            {
                sp.Close();
            }
        }
      

  4.   

    可问题是我用的是高通800cdma模块,模块本身不支持长短信发送,所以无法让短信中心知道你发的是长短信
      

  5.   


    zong = textBox1.Text;
                char [] fen = zong.ToCharArray ();
                int n = (zong.Length+69)/70; //除数为分割的字符串的长度
                string[] strfen = new string[n];
                
                for (int i = 0,j=0; i < n; i++)
                {
                    string b = null;
                    for (int x = 0; x < 70; x++) //小于的也是字符串的长度
                    {
                        
                        if ((x+j)<zong.Length )
                        {
                            b = b + fen[x + j].ToString ();
                        }
                    }
                    strfen[i] = "@" + b + "@";
                    
                 //   strfen[i] = "@"+fen[j].ToString() + fen[j + 1].ToString() + fen[j + 2].ToString()+"@";
                    j = j + 70;  //加的也是字符串的长度
                }
                strfen[0] = strfen[0].Remove(0, 1);
                strfen[n-1] = strfen[n-1].Remove(strfen[n-1].Length - 1, 1);
    这是我写的拆分部分,目前加的标识符只是"@",至少还要加上号码和时间戳
      

  6.   

    cdma与gsm短信协议是一样的啊。手机的长短信其实也不是模块自动支持,而是手机上层程序在重组。你的PC接收时,是可以按照自定义协议重组,但这需要用手机的那一方在短信中写特定格式吧?