现在的位置: 首页 > 综合 > 正文

发送 彩信

2014年02月08日 ⁄ 综合 ⁄ 共 12916字 ⁄ 字号 评论关闭

 http://blog.csdn.net/axman/article/details/1671531

 

 mms如果不支持smil那就不能叫真正的MMS,mixed的格式对于多个附件的MMS来说不仅没有"排版"功能,

而且即使用你想一个文件一个文件"拆单了看",也不得不看一次手工播放一次,就象要手动"翻页".所以不支持

smil干脆就别玩MMS了.

但基于related格式的支持smil的PDU打包方式怎么也搜索不到,很多厂商和技术人员都故作神秘,不就是一

堆规范的实现吗?只好下了几个文档来研究,经过反复调试,其中用nowSMS的mmscomp打包出来的格式竟然

是错误的,最后多次抓包比较,总算成功了.在『别人原来的mixed方式』的基础上修改成related方式的.有需要的

就自己用去吧.(注意基础类是别人原来提供的,我只是提供了related方式的打包逻辑)

工程文件在:http://dl2.csdn.net/down4/20070706/06201955542.rar

 

using System;
using System.Net;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Collections;
using System.Text;
/// <summary>
/// Lib 的摘要说明
/// </summary>

namespace MMSLib
{

    public class MMessage
    {
        
string subject = "测试";
        
int deliverTime = 0;   //   多少秒以后开始投递
        ArrayList inlineFiles = new ArrayList();       //   文件列表  
        ArrayList destinations = new ArrayList();      //   目标号码  

        
static long serialNumber = 19700311L;                  //   流水号
        FileInfo smilFile;

        public void SetSubject(string subject)
        {
            
this.subject = subject;
        }
        
public void SetDeliverTime(int deliverTime)
        {
            
this.deliverTime = deliverTime;
        }
        
//    
        public void AddTo(string dest)
        {
            destinations.Add(dest);
        }

        public void AddFile(string file)
        {

            if (file.ToLower().EndsWith(".smil"))
            {
                
if (this.smilFile != null)
                    
throw new Exception("The smil file has existed!");
                
this.smilFile = new FileInfo(file);
            }
            inlineFiles.Add(file);
        }

        public void ClearTo()
        {
            destinations.Clear();
        }

        //   得到二进制编码字节  
        public byte[] MakeMMSContent()
        {

            if (this.smilFile == nullthrow new Exception("The smil file not found!");

            byte[] MMSContent = new byte[0];
 
            
//X-Mms-Message-Type  
            MMSContent = appendContent(new byte[] { 0x8C0x80 }, MMSContent);

            
            //X-Mms-Transaction-ID  
            MMSContent = appendContent(new byte[] { 0x98 }, MMSContent);
            MMSContent 
= appendContent(serialNumber.ToString(), MMSContent);
            serialNumber
++;   

            MMSContent = appendContent(new byte[] { 0x0 }, MMSContent);

            //X-Mms-MMS-Version  
            MMSContent = appendContent(new byte[] { 0x8D0x90 }, MMSContent);

            //Date  
            MMSContent = appendContent(new byte[] { 0x85 }, MMSContent);
            TimeSpan ts 
= DateTime.Now - new DateTime(197011000);
            
int sec = (int)ts.TotalSeconds;
            
byte[] bySec = BitConverter.GetBytes(sec);
            MMSContent 
= appendContent(new byte[] { (byte)bySec.Length }, MMSContent);
            Array.Reverse(bySec);
            MMSContent 
= appendContent(bySec, MMSContent);

            if (deliverTime > 0)
            {
                MMSContent 
= appendContent(new byte[] { 0x87 }, MMSContent);
                
byte[] bfTime = BitConverter.GetBytes(deliverTime);     
                Array.Reverse(bfTime);
                
byte[] bfTimeLen = new byte[3];
                bfTimeLen[
0= (byte)(bfTime.Length + 2);
                bfTimeLen[
1= 0x81;     //   相对时间格式  
                bfTimeLen[2= (byte)bfTime.Length;
                MMSContent 
= appendContent(bfTimeLen, MMSContent);
                MMSContent 
= appendContent(bfTime, MMSContent);
            }

            //From,Len = 0x01,一个以0x81为标记的占位符,发送时自动插入发送号码.
            MMSContent = appendContent(new byte[] { 0x890x010x81 }, MMSContent);

            //To  
            for (int i = 0; i < destinations.Count; i++)
            {
                MMSContent 
= appendContent(new byte[] { 0x97 }, MMSContent);
                MMSContent 
= appendContent("+86" + (string)destinations[i] + "/TYPE=PLMN", MMSContent);
                
//MMSContent = appendContent(new byte[] { 0x20, 0x20, 0x0 }, MMSContent);
                MMSContent = appendContent(new byte[] { 0x0 }, MMSContent);
            }

            //subject  
            if (subject.Length > 0)     //   使用Utf8编码  
            {
                MMSContent 
= appendContent(new byte[] { 0x96 }, MMSContent);
                
byte[] byLen = new byte[1];
                byLen[
0= (byte)(Encoding.UTF8.GetByteCount(subject) + 2);
                MMSContent 
= appendContent(byLen, MMSContent);
                MMSContent 
= appendContent(new byte[] { 0xEA }, MMSContent);
                MMSContent 
= appendContent(Encoding.UTF8.GetBytes(subject), MMSContent);
                MMSContent 
= appendContent(new byte[] { 0x0 }, MMSContent);
            }

            MMSContent = appendContent(new byte[] { 0x84 }, MMSContent);
            
int ctLen = 2   // 0xB3 ,0x89
                +  "application/smil".Length
                
+ 3         //0x00 0x8A 0x3c
                + smilFile.Name.Length
                
+ 2;         //0x3c,0x00

            
byte[] cl = uintToBytes(ctLen);

            if(cl[0>= 0x1F)
                MMSContent 
= appendContent(new byte[] { 0x1F }, MMSContent);
            MMSContent 
= appendContent(cl, MMSContent);
            MMSContent 
= appendContent(new byte[] { 0xB3}, MMSContent);
                
//0xB3   Content-Type:application/vnd.wap.multipart.related
            
            MMSContent 
= appendContent(new byte[] { 0x89 }, MMSContent);
            MMSContent 
= appendContent(Encoding.ASCII.GetBytes("application/smil"), MMSContent);
            MMSContent 
= appendContent(new byte[] { 0x0 }, MMSContent);

            MMSContent = appendContent(new byte[] { 0x8A ,0x3C}, MMSContent);//0x8A:Start,0x3C:<
            MMSContent = appendContent(Encoding.ASCII.GetBytes( smilFile.Name ), MMSContent);
            MMSContent 
= appendContent(new byte[] { 0x3E ,0x0 }, MMSContent); //0x3E:>

            byte[] byFileCount = new byte[1];
            byFileCount[
0= (byte)inlineFiles.Count;
            MMSContent 
= appendContent(byFileCount, MMSContent);

            int chLen = "application/smil".Length 
            
+ 4     //0x00 0xc0 0x22 0x3c: cid,",<
            + smilFile.Name.Length
            
+ 3     // 0x3E,0x00,0x8E
            + smilFile.Name.Length
            
+ 1;     // 0x00
            
            
for (int j = 0; j < inlineFiles.Count; j++)
            {
                MMSContent 
= appendContent(GetFileContent(inlineFiles[j].ToString()), MMSContent);
            }
            
return MMSContent;
        }

        //   打包文件
        private byte[] GetFileContent(string FileName)
        {

            byte[] byHeaders = new byte[0];       //   ContentType和Headers组合  
            byte[] byData = readFile(FileName);

            string FileID = getContentId(FileName);
            
if (FileName.EndsWith(".txt"))
            {
                byHeaders 
= new byte[1];
                byHeaders[
0= (byte)(Encoding.ASCII.GetByteCount(FileID) + 5);
                byHeaders 
= appendContent(new byte[] { 0x830x85 }, byHeaders);       //   Utf-8  
                byHeaders = appendContent(Encoding.ASCII.GetBytes(FileID), byHeaders);
                byHeaders 
= appendContent(new byte[] { 0x00 }, byHeaders);
                byHeaders 
= appendContent(new byte[] { 0x810xEA }, byHeaders);

            }
            else if (FileName.EndsWith(".gif"))
            {
                byHeaders 
= new byte[] { 0x9D };
            }
            
else if (FileName.EndsWith(".mid"|| FileName.EndsWith(".midi"))
            {
                byHeaders 
= Encoding.ASCII.GetBytes("audio/midi");
                byHeaders 
= appendContent(new byte[] { 0x00 }, byHeaders);     
            }
            
else if (FileName.EndsWith(".smil"))
            {
                byHeaders 
= Encoding.ASCII.GetBytes("application/smil");
                byHeaders 
= appendContent(new byte[] { 0x00 }, byHeaders);     
            }

            //加入Content-ID 
            byHeaders = appendContent(new byte[] { 0xC00x220x3C }, byHeaders);
            byHeaders 
= appendContent(Encoding.ASCII.GetBytes(FileID), byHeaders);
            byHeaders 
= appendContent(new byte[] { 0x3E0x00 }, byHeaders);
            
            
//加入Content-Location  
            byHeaders = appendContent(new byte[] { 0x8E }, byHeaders);
            byHeaders 
= appendContent(Encoding.ASCII.GetBytes(FileID), byHeaders);
            byHeaders 
= appendContent(new byte[] { 0x00 }, byHeaders);

            byte[] byHeaderLen = uintToBytes(byHeaders.Length);
            
byte[] byDataLen = uintToBytes(byData.Length);

            byte[] byMmc = new byte[byHeaderLen.Length + byDataLen.Length + byHeaders.Length + byData.Length];
            Array.Copy(byHeaderLen, byMmc, byHeaderLen.Length);
            Array.Copy(byDataLen, 
0, byMmc, byHeaderLen.Length, byDataLen.Length);
            Array.Copy(byHeaders, 
0, byMmc, byHeaderLen.Length + byDataLen.Length, byHeaders.Length);
            Array.Copy(byData, 
0, byMmc, byHeaderLen.Length + byDataLen.Length + byHeaders.Length, byData.Length);

            return byMmc;
        }

        private byte[] uintToBytes(int n)
        {
            
byte[] buf = new byte[8];
            
int l = 0;
            
while (n >= 128)
            {
                
byte b = (byte)(n & 0x7F);
                n 
= n >> 7;
                buf[l
++= b;
            }
            buf[l
++= (byte)n;

            byte[] retBys = new byte[l];
            
for (int i = 0; i < l; ++i)
            {
                retBys[i] 
= (byte)(buf[l - i - 1| 0x80);
            }
            retBys[l 
- 1&= 0x7F;
            
return retBys;

        }
        
        //   读取文件  
        private byte[] readFile(string FileName)
        {
            
if (FileName.EndsWith(".txt")) {

                StreamReader sr = null;
                
try{
                    sr 
= new StreamReader(FileName, Encoding.Default);
                    
string text = sr.ReadToEnd();
                    
byte[] bf = Encoding.UTF8.GetBytes(text);
                    
return bf;
                }
                
catch {
                    
return new byte[0];
                }
                
finally {
                    
if (sr != null) sr.Close();
                }
            }
            FileStream fs 
= null;
            
try
            {
                fs 
= new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);     //   没有设定Buffsize  
                byte[] bf = new byte[fs.Length];
                fs.Read(bf, 
0, (int)fs.Length);
                
return bf;
            }
            
catch{
                
return new byte[0];
            }
            
finally{
                
if(fs != null) fs.Close();
            }
        }
        
        
private string getContentId(string FileName)
        {
            
int at = FileName.LastIndexOf("/");
            
if (at < 0)
                at 
= FileName.LastIndexOf("/");
            
return FileName.Substring(at + 1);
        }
  
        
private byte[] appendContent(byte[] srcBys, byte[] destBys)
        {
            Array.Resize(
ref destBys, srcBys.Length + destBys.Length);
            Array.Copy(srcBys,
0,destBys,destBys.Length - srcBys.Length,srcBys.Length);
            
return destBys;
        }

        private byte[] appendContent(string sz, byte[] byDest)
        {
            
return appendContent(Encoding.Default.GetBytes(sz), byDest);
        }
    }

    ///   <summary>  
    
///   MMSender   的摘要说明。  
    
///    
    
///   </summary>  
    public class MMSender
    {
        
//   设置参数  
        string sMmscUrl = "http://mmsc.monternet.com";
        
string sProxyUrl = "10.0.0.172:80";

        public MMSender()
        {
            
//  
            
//   TODO:   在此处添加构造函数逻辑  
            
//  
        }
        
public void SetMMSC(string szUrl)
        {
            sMmscUrl 
= szUrl;
        }
        
public void SetProxy(string szUrl)
        {
            sProxyUrl 
= szUrl;
        }

        /*   发送MMS的过程  
        1>   创建消息发送接口  
            MMSender   ms   =   new   MMSender();  
        2>   设置参数属性  
            默认属性已经是中国移动参数,因此如果是中国移动用户,以下两个操作可以不需要  
            ms.SetMMSC("
http://mmsc.monternet.com");  
            ms.SetProxy("10.0.0.172:80");  
        3>   创建消息  
            MMessage   mm=   new   MMessage();  
        4>   设置消息内容  
            mm.SetSubject("标题");             //   设置标题  
            mm.AddTo("13810034500");         //   添加接收号码,调用一次添加一个接收号码  
            mm.AddFile("FileName");           //   添加发送文件,包含文件路径,调用一次添加一个发送文件  
        5>   发送消息  
              string   szReult   =ms.Send(mm);  
         
        6>   继续发送其他号码  
            mm.ClearTo();  
            mm.AddTo("13812345678");  
            ms.Send(mm);            
        
*/

        /*   避免协议冲突的设置  
        <configuration>  
        <system.net>  
        <settings>  
        <httpWebRequest   useUnsafeHeaderParsing="true"/>  
        </settings>  
        </system.net>  
        </configuration>  
                
*/

        public string Send(MMessage mm)
        {
            
try
            {
                
byte[] byMM = mm.MakeMMSContent();
                
if (byMM.Length > 50 * 1024)
                    
return "

抱歉!评论已关闭.