天天看点

【国际短信】功能开发经验及具体开发实现

经过通道测试,目前支持大多数国家和地区,下面提供C#和Java两种编程语言的Demo示例。

一、国际短信SDK:

http://sdk2.entinfo.cn:8060/gjWebService.asmx/mdSmsSend_g? sn=string&pwd=string&mobile=string

&content=string&ext=string&stime=string&rrid=string

sn即您注册时的序列号,pwd需要MD5(SN+pwd)加密,取32位大写。

示例:

http://sdk2.entinfo.cn:8060/gjWebService.asmx/mdSmsSend_g?sn=SDK-SSD-010-xxxxx&pwd=F561FBB2B012D611B0028EA96272D8B7&mobile=008615321858155&content=test message&ext=&stime=&rrid=

参数名称 说明 是否必须    备注
sn 软件序列号 格式XXX-XXX-XXX-XXXXX
pwd 密码 md5(sn+password) 32位大写密文
mobile 手机号 必填(支持1000个手机号,建议<=800)多个英文逗号隔开
Content 内容 支持长短信(详细请看长短信扣费说明)
Ext 扩展码 例如:123(默认置空)
stime 定时时间 例如:2010-12-29 16:27:03(非定时短信置空)
Rrid 唯一标识 最长18位

函数返回值:String(唯一标识,即当前发送短信批次的唯一标识,和rrid对应,如为空则返回系统生成的rrid)

以下是 HTTP POST 请求和响应示例。所显示的占位符需替换为实际值。
		POST /gjWebService.asmx/mdSmsSend_g HTTP/1.1
		Host: sdk2.entinfo.cn
		Content-Type: application/x-www-form-urlencoded
		Content-Length: length
		sn=string&pwd=string&mobile=string&content=string&ext=string&stime=string&rrid=string
		--------------------------------------
		HTTP/1.1 200 OK
		Content-Type: text/xml; charset=utf-8
		Content-Length: length
		<?xml version="1.0" encoding="utf-8"?>
		<string xmlns="http://tempuri.org/">string</string>
           

二、PHP国际短信示例代码

<?PHP 
//改demo的功能是群发短信和发单条短信。(传一个手机号就是发单条,多个手机号既是群发)

//您把序列号和密码还有手机号,填上,直接运行就可以了

//如果您的系统是utf-8,请转成GB2312 后,再提交、
//请参考 'content'=>iconv( "UTF-8", "gb2312//IGNORE" ,$content),//短信内容

$flag = 0; 
        //要post的数据 
$argv = array( 
         'sn'=>'SDK-SSD-010-XXXXX', 替换成您自己的序列号
		 'pwd'=>strtoupper(md5('SDK-SSD-010-XXXXX'.'11111111')), //此处密码需要加密 加密方式为 md5(sn+password) 32位大写
		 'mobile'=>'008613718331021',//手机号 多个用英文的逗号隔开 post理论没有长度限制.推荐群发一次小于等于10000个手机号
		 'content'=>'您好测试國際短信[签名]',//短信内容
		 'ext'=>'',
		 'rrid'=>'',//默认空 如果空返回系统生成的标识串 如果传值保证值唯一 成功则返回传入的值
		 'stime'=>''//定时时间 格式为2011-6-29 11:09:21
		 ); 
//构造要post的字符串 
foreach ($argv as $key=>$value) { 
          if ($flag!=0) { 
                         $params .= "&"; 
                         $flag = 1; 
          } 
         $params.= $key."="; $params.= urlencode($value); 
         $flag = 1; 
          } 
         $length = strlen($params); 
                 //创建socket连接 
        $fp = fsockopen("sdk2.entinfo.cn",8060,$errno,$errstr,10) or exit($errstr."--->".$errno); 
         //构造post请求的头 
         $header = "POST /gjwebservice.asmx/mdSmsSend_g HTTP/1.1\r\n"; 
         $header .= "Host:sdk2.entinfo.cn\r\n"; 
         $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
         $header .= "Content-Length: ".$length."\r\n"; 
         $header .= "Connection: Close\r\n\r\n"; 
         //添加post的字符串 
         $header .= $params."\r\n"; 
         //发送post的数据 
         fputs($fp,$header); 
         $inheader = 1; 
          while (!feof($fp)) { 
                         $line = fgets($fp,1024); //去除请求包的头只显示页面的返回数据 
                         if ($inheader && ($line == "\n" || $line == "\r\n")) { 
                                 $inheader = 0; 
                          } 
                          if ($inheader == 0) { 
                                // echo $line; 
                          } 
          } 
		  //<string xmlns="http://tempuri.org/">-5</string>
	       $line=str_replace("<string xmlns=\"http://tempuri.org/\">","",$line);
	       $line=str_replace("</string>","",$line);
		   $result=explode("-",$line);
		    if(count($result)>1)
			echo '发送失败返回值为:'.$line;
			else
			echo '发送成功 返回值为:'.$line;  
?>

           

三、C#国际短信示例代码

1.配置文件app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="国际短信.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <applicationSettings>
        <国际短信.Properties.Settings>
            <setting name="国际短信_GlobalMessage_gjWebService" serializeAs="String">
                <value>http://sdk2.entinfo.cn:8060/gjWebService.asmx</value>
            </setting>
        </国际短信.Properties.Settings>
    </applicationSettings>
</configuration>
           

2.GlobalMessage

//------------------------------------------------------------------------------
// <auto-generated>
//     此代码由工具生成。
//     运行时版本:4.0.30319.1
//
//     对此文件的更改可能会导致不正确的行为,并且如果
//     重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

// 
// 此源代码是由 Microsoft.VSDesigner 4.0.30319.1 版自动生成。
// 
#pragma warning disable 1591

namespace 国际短信.GlobalMessage {
    using System;
    using System.Web.Services;
    using System.Diagnostics;
    using System.Web.Services.Protocols;
    using System.ComponentModel;
    using System.Xml.Serialization;
    
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name="gjWebServiceSoap", Namespace="http://tempuri.org/")]
    public partial class gjWebService : System.Web.Services.Protocols.SoapHttpClientProtocol {
        
        private System.Threading.SendOrPostCallback mdSmsSend_gOperationCompleted;
        
        private bool useDefaultCredentialsSetExplicitly;
        
        /// <remarks/>
        public gjWebService() {
            this.Url = global::国际短信.Properties.Settings.Default.国际短信_GlobalMessage_gjWebService;
            if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
                this.UseDefaultCredentials = true;
                this.useDefaultCredentialsSetExplicitly = false;
            }
            else {
                this.useDefaultCredentialsSetExplicitly = true;
            }
        }
        
        public new string Url {
            get {
                return base.Url;
            }
            set {
                if ((((this.IsLocalFileSystemWebService(base.Url) == true) 
                            && (this.useDefaultCredentialsSetExplicitly == false)) 
                            && (this.IsLocalFileSystemWebService(value) == false))) {
                    base.UseDefaultCredentials = false;
                }
                base.Url = value;
            }
        }
        
        public new bool UseDefaultCredentials {
            get {
                return base.UseDefaultCredentials;
            }
            set {
                base.UseDefaultCredentials = value;
                this.useDefaultCredentialsSetExplicitly = true;
            }
        }
        
        /// <remarks/>
        public event mdSmsSend_gCompletedEventHandler mdSmsSend_gCompleted;
        
        /// <remarks/>
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/mdSmsSend_g", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public string mdSmsSend_g(string sn, string pwd, string mobile, string content, string ext, string stime, string rrid) {
            object[] results = this.Invoke("mdSmsSend_g", new object[] {
                        sn,
                        pwd,
                        mobile,
                        content,
                        ext,
                        stime,
                        rrid});
            return ((string)(results[0]));
        }
        
        /// <remarks/>
        public void mdSmsSend_gAsync(string sn, string pwd, string mobile, string content, string ext, string stime, string rrid) {
            this.mdSmsSend_gAsync(sn, pwd, mobile, content, ext, stime, rrid, null);
        }
        
        /// <remarks/>
        public void mdSmsSend_gAsync(string sn, string pwd, string mobile, string content, string ext, string stime, string rrid, object userState) {
            if ((this.mdSmsSend_gOperationCompleted == null)) {
                this.mdSmsSend_gOperationCompleted = new System.Threading.SendOrPostCallback(this.OnmdSmsSend_gOperationCompleted);
            }
            this.InvokeAsync("mdSmsSend_g", new object[] {
                        sn,
                        pwd,
                        mobile,
                        content,
                        ext,
                        stime,
                        rrid}, this.mdSmsSend_gOperationCompleted, userState);
        }
        
        private void OnmdSmsSend_gOperationCompleted(object arg) {
            if ((this.mdSmsSend_gCompleted != null)) {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.mdSmsSend_gCompleted(this, new mdSmsSend_gCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }
        
        /// <remarks/>
        public new void CancelAsync(object userState) {
            base.CancelAsync(userState);
        }
        
        private bool IsLocalFileSystemWebService(string url) {
            if (((url == null) 
                        || (url == string.Empty))) {
                return false;
            }
            System.Uri wsUri = new System.Uri(url);
            if (((wsUri.Port >= 1024) 
                        && (string.Compare(wsUri.Host, "localHost", System.StringComparison.OrdinalIgnoreCase) == 0))) {
                return true;
            }
            return false;
        }
    }
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]
    public delegate void mdSmsSend_gCompletedEventHandler(object sender, mdSmsSend_gCompletedEventArgs e);
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    public partial class mdSmsSend_gCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
        
        private object[] results;
        
        internal mdSmsSend_gCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 
                base(exception, cancelled, userState) {
            this.results = results;
        }
        
        /// <remarks/>
        public string Result {
            get {
                this.RaiseExceptionIfNecessary();
                return ((string)(this.results[0]));
            }
        }
    }
}

#pragma warning restore 1591
           

3.调用GlobalMessage.gjWebService

using System;
using System.Text;
using System.Windows.Forms;
using System.Web.Security;

namespace 国际短信
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void textBox3_Enter(object sender, EventArgs e)
        {
            if ( Phone.Text == "多个手机号用英文逗号隔开")
            {
                Phone.Text = "";
            }
           
        }

        private void Phone_Leave(object sender, EventArgs e)
        {
            if (Phone.Text == "")
            {
                Phone.Text = "多个手机号,用英文的逗号隔开";
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string sn = SN.Text.Trim();
            if(sn.Length==0)
            {
                MessageBox.Show("请填序列号!");
                return;
            }

            string pwd = PWD.Text.Trim();
            if (pwd.Length == 0)
            {
                return;
            }

            string phone = Phone.Text;
            if (phone.Length == 0 || phone == "多个手机号用英文逗号隔开")
            {
                MessageBox.Show("请填手机号!");
                return;
            }
            GlobalMessage.gjWebService sms = new GlobalMessage.gjWebService();
            pwd = FormsAuthentication.HashPasswordForStoringInConfigFile(sn + pwd, "md5");       
            
           
            string result = sms.mdSmsSend_g(sn, pwd, phone, Content.Text, "", "", "");
            Content.AppendText("\n发送完毕,返回值为:" + result);
        }

    }
}
           

四、Java国际短信示例代码

1.Client.java类

package com;

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.w3c.dom.Document; 
import org.w3c.dom.NodeList; 
import java.io.UnsupportedEncodingException;
public class Client {

	/*
	 * webservice服务器定义
	 */
	private String serviceURL = "http://sdk2.entinfo.cn:8060/gjWebService.asmx";

	private String sn = "";// 序列号

	private String password = "";

	private String pwd = "";// 密码
	Document document = null; 

	NodeList allNode = null; 
	/*
	 * 构造函数
	 */
	public Client(String sn, String password)
			throws UnsupportedEncodingException {
		this.sn = sn;
		this.password = password;
		this.pwd = this.getMD5(sn + password);
	}

	/*
	 * 方法名称:getMD5 功 能:字符串MD5加密 参 数:待转换字符串 返 回 值:加密之后字符串
	 */
	public String getMD5(String sourceStr) throws UnsupportedEncodingException {
		String resultStr = "";
		try {
			byte[] temp = sourceStr.getBytes();
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(temp);
			// resultStr = new String(md5.digest());
			byte[] b = md5.digest();
			for (int i = 0; i < b.length; i++) {
				char[] digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
						'9', 'A', 'B', 'C', 'D', 'E', 'F' };
				char[] ob = new char[2];
				ob[0] = digit[(b[i] >>> 4) & 0X0F];
				ob[1] = digit[b[i] & 0X0F];
				resultStr += new String(ob);
			}
			return resultStr;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		}
	}
	/*
	 * 方法名称:mdSmsSend_g 功 能:发送短信 参
	 * 数:mobile,content,ext,stime,rrid(手机号,内容,扩展码,定时时间,唯一标识) 返 回
	 * 值:唯一标识,如果不填写rrid将返回系统生成的
	 */
	public String mdSmsSend_g(String mobile, String content, String ext, String stime,
			String rrid) {
		String result = "";
		String soapAction = "http://tempuri.org/mdSmsSend_g";
		String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
		xml += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
		xml += "<soap:Body>";
		xml += "<mdSmsSend_g xmlns=\"http://tempuri.org/\">";
		xml += "<sn>" + sn + "</sn>";
		xml += "<pwd>" + pwd + "</pwd>";
		xml += "<mobile>" + mobile + "</mobile>";
		xml += "<content>" + content + "</content>";
		xml += "<ext>" + ext + "</ext>";
		xml += "<stime>" + stime + "</stime>";
		xml += "<rrid>" + rrid + "</rrid>";
		xml += "</mdSmsSend_g>";
		xml += "</soap:Body>";
		xml += "</soap:Envelope>";

		URL url;
		try {
			url = new URL(serviceURL);

			URLConnection connection = url.openConnection();
			HttpURLConnection httpconn = (HttpURLConnection) connection;
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			bout.write(xml.getBytes());
			byte[] b = bout.toByteArray();
			httpconn.setRequestProperty("Content-Length", String
					.valueOf(b.length));
			httpconn.setRequestProperty("Content-Type",
					"text/xml; charset=gb2312");
			httpconn.setRequestProperty("SOAPAction", soapAction);
			httpconn.setRequestMethod("POST");
			httpconn.setDoInput(true);
			httpconn.setDoOutput(true);

			OutputStream out = httpconn.getOutputStream();
			out.write(b);
			out.close();

			InputStreamReader isr = new InputStreamReader(httpconn
					.getInputStream());
			BufferedReader in = new BufferedReader(isr);
			String inputLine;
			while (null != (inputLine = in.readLine())) {
				Pattern pattern = Pattern
						.compile("<mdSmsSend_gResult>(.*)</mdSmsSend_gResult>");
				Matcher matcher = pattern.matcher(inputLine);
				while (matcher.find()) {
					result = matcher.group(1);
				}
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
}
           

2.发送调用

package com;
public class Demo_Client {

	public static void main(String[] args) throws Exception {

		String sn = "SDK-SSD-010-";// 请替换为自己的序列号和密码
		String pwd = "XXXXX";// 替换自己的密码
		Client client = new Client(sn, pwd);
		String result_send = client.mdSmsSend_g("0010XXXXXXX", "您的信件已经寄出[雷雨科技]", "",
				"", "");
		if (!result_send.startsWith("-") && !result_send.equals("")) {
			System.out.println("发送成功,返回值为:" + result_send);
		} else {
			System.out.println("发送失败,返回值为:" + result_send);
		}

	}
}
           

五、webservice返回值(XML格式的字符串)

返回值 返回值说明 问题描述
-1 重复注册 多次点击“注册”按钮或注册方法(Register)的“调用”按钮
-2  帐号/密码不正确 1.序列号未注册2.密码加密不正确3.密码已被修改4.序列号已注销
-4 余额不足支持本次发送 直接调用查询看是否余额为0或不足
-5 数据格式错误 只能自行调试了。或与技术支持联系
-6 参数有误 看参数传的是否均正常,请调试程序查看各参数
-9 扩展码权限错误 该序列号是否已经开通了扩展子号的权限,把ext这个参数置空。
-10 内容长度长 短信内容过长,纯单字节不能超过1000个,双字节不能超过500个字符2.彩信不得超过50KB
-12 序列号状态错误 序列号是否被禁用
-14 服务器写文件失败
-18 上次提交没有等待返回不能继续提交 默认不支持多线程
-19 禁止同时使用多个接口地址 每个序列号提交只能使用一个接口地址
-20 相同手机号,相同内容重复提交
-22 Ip鉴权失败 提交的IP不是所绑定的IP

注:以上返回值针对个别方法.请具体参看每个用到方法的详细说明。

六、附加说明:

1. 禁止相同的内容多个手机号连续一条一条提交. 否则禁用帐号,由此带来损失由客户自行负责.我们推荐客户能群发就群发

2.所有帐号提交短信,必须等上一批提交返回后再提交下一批(默认不支持多线程并发)

3.一次提交内容建议不要超过140字符,超过70个字符此时出现长短信的概念.

如果一次提交小于等于70字符 系统会默认为一条短信发出 扣费12条

如果大于70字符 系统会默认为长短信处理 此时根据长短信前边会加(1/2) 或者(2/2)的标志 此时扣费按67字符扣12条。纯单字节是160字符以内12条,超过160个字符后,按普通长短信收费,即67个字符每12条收费。

4. 请客户提供外网服务器IP以便于绑定IP发送,提高账号的安全性!

5.各个发短信的方法,都没有数据合法性的验证。请您在提交之前,做好此项工作,以避免不必要的扣费。

6.同一批次里,相同的手机号,只会收到一条短信

7.,请填写完整的手机信息:“国际区码+城市地区代号+手机号码” 填写国际手机号码的时候,手机号码前必须填写“00”

如:以德国手机举例:国际区码:49,地区区码:0179,手机号码:1234567 

填写的正确格式为:00491791234567

8.给大陆手机号发短信,建议走普通接口

地址:http://sdk2.entinfo.cn:8060/gjWebService.asmx

这些地址都是标准的webservice地址,C#,Java客户可以按照自己熟悉的方式去解析

或者

地址:http://sdk2.entinfo.cn:8060/gjWebService.asmx?wsdl

七、示例Demo源代码下载:

DEMO(PHP版本)  DEMO(C#版本)  DEMO(Java版本)  SDK通用版接口文档  所有下载