一、推送方式
用户通过如下地址设置url参数,以下蓝色部分为用户自定义参数,%XXX%固定。
用户提供接收上行的url,采用post方式推送
http://www.url.com/mo.aspx?args=%XXX%
%XXX%格式如下:
mo ID,特服号,手机号,内容(对内容进行gb2312解码),时间,如有多条以英文“;”隔开,最多1000条
123456,62891,138****065,ceshi01,2009-10-19 15:51:05;123456,62891,139****404,test02,2009-10-19 15:51:17
返回:0接收成功,其它或异常返回
注:moid 推送的时候是固定值(123456),因为这个参数没有太大的意义 您们在保存数据的时候这一参数可以忽略;如果您要保存请不要把它设成主键。
二、C++短信回复示例代码
struct RECV_MSG //定义结构
{
CString csRevevieID;
CString csSendNum;
CString csContent;
CString csTime;
CString csExCode;//特服号+扩展码组成的号码
};
1.获取并记录短信回复内容RecevieSMS()
void CSendSMS_REPLY::RecevieSMS()//获取一次,然后内容插入数据库记录,用于更新显示
{
CWebInterface WebInterface (Pregister->szSerNO,Pregister->csPWD);
CArray< RECV_MSG,RECV_MSG&> caRevevieMSG;
int iState=WebInterface.RecevieMSG(caRevevieMSG);//解码后的所有短信结构数组.
if (WEBS_RET_FAIL==iState)
{
MessageBox(_T("没有需要接收的短信."),MESSAGE_INFO,MB_OK|MB_ICONWARNING);
return;
}
int iCount=caRevevieMSG.GetCount();
if (0==iCount)
{
return;
}
CString csStartTime,csEndTime;//多条短信累计接收时候,记录第一条记录的时间和最后一条记录的时候。因为不知道接口返回结果记录的顺序,所以后面来判断取最小的
CDatabase db;
db.Open(NULL,false,false,theApp.strDsn,TRUE);
db.GetConnect();
for(int i=0;i<=iCount;i++)
{
RECV_MSG stOneMSG=caRevevieMSG.GetAt(i);
char *pError=NULL;
CString csSQL;
COleDateTime ctSendTime;
ctSendTime.ParseDateTime(stOneMSG.csTime);
stOneMSG.csTime=ctSendTime.Format(_T("%Y-%m-%d %H:%M:%S"));//格式化为:csTime
stOneMSG.csContent.Replace(_T("'"),_T("''"));//CString csContent;
int nSeReNum;
CString csExNum= stOneMSG.csExCode.Right(stOneMSG.csExCode.GetLength()-Pregister->csCode.GetLength());//CString csExCode
if (csExNum.IsEmpty())
{
nSeReNum=-1;
}
else
{
char *pExNum = UnicodeToANSI(csExNum);
nSeReNum=atoi(pExNum);
free(pExNum);
}
CString lianxiren;
lianxiren=GetName(stOneMSG.csSendNum);//取得联系人名字
db.ExecuteSQL(_T("insert into [RevevieMSG] (csRevevieID,lianxiren,csSendNum,csContent,csTime,csExCode) values ('"+stOneMSG.csRevevieID+"','"+lianxiren+"','"+stOneMSG.csSendNum+"','"+stOneMSG.csContent+"','"+stOneMSG.csTime+"','"+csExNum+"') "));
if(0==i)
{
csStartTime = stOneMSG.csTime;
}
if (iCount-1 == i)
{
csEndTime = stOneMSG.csTime;
}
}
db.Close();
update_data(_T("select * from [RevevieMSG] order by id desc"));
}
2.获取短信回复内容RecevieMSG(CArray< RECV_MSG,RECV_MSG&> &caRevevieMSG)
int CWebInterface::RecevieMSG(CArray< RECV_MSG,RECV_MSG&> &caRevevieMSG)
{
_ns1__mo param1;
_ns1__moResponse WebsResult;
param1.sn = m_pSN;
param1.pwd =m_pMd5;
//WRITE_LOG_LW("call mo");
SetTimeout(150);
int nRet =m_WebService.__ns2__mo(¶m1,&WebsResult);
if (nRet)
{
char szLog[128];
sprintf(szLog,"Error,mo,nRet=%d",nRet);
//g_LogRun.WriteLog(szLog);
//::MessageBox(0,_T("网络错误."),CompanyInfo.csCompanyInfo,MB_OK|MB_ICONERROR);
return WEBS_RET_FAIL;
}
int nSvrRet =atoi(WebsResult.moResult);//strtoul(WebsRet.mdSmsSendResult,0,10);
if (nSvrRet>1)
{
int nLogBufLen = strlen(WebsResult.moResult)+128;
char *pLogBuf = new char[nLogBufLen];
sprintf(pLogBuf,"mo,webResult=%s",WebsResult.moResult);
//g_LogRun.WriteLog(pLogBuf);
delete [] pLogBuf;
}
if (1==nSvrRet || nSvrRet< 0)
{
return WEBS_RET_FAIL;
}
CString csRecevieContent;
csRecevieContent=WebsResult.moResult;
CStringArray csaRecevieContent;
gSplit(csRecevieContent,csaRecevieContent,_T("\r\n"));//每条短信用回车换行隔开.
int iCount=csaRecevieContent.GetCount();
for(int i=0;i< iCount;i++)
{
CString csOneMSG=csaRecevieContent.GetAt(i);
CStringArray csaOneMSG;
gSplit(csOneMSG,csaOneMSG,_T(","));//一条短信内各部分用","隔开.
RECV_MSG stMSG;
stMSG.csRevevieID=csaOneMSG.GetAt(0);//第二个元素为接收者的特服号
stMSG.csExCode=csaOneMSG.GetAt(1);//特服号+扩展码组成的号串
stMSG.csSendNum=csaOneMSG.GetAt(2);
stMSG.csContent=csaOneMSG.GetAt(3);
stMSG.csTime=csaOneMSG.GetAt(4);
stMSG.csExCode.Replace(_T(","),_T(""));
stMSG.csSendNum.Replace(_T(","),_T(""));
stMSG.csContent.Replace(_T(","),_T(""));
stMSG.csTime.Replace(_T(","),_T(""));
char szTemp[1024]={0};
char *pszTemp = UnicodeToANSI(stMSG.csContent);
int nDecodeLen =UrlDecode(pszTemp,strlen(pszTemp));
WCHAR *wpTemp=ANSIToUnicode(pszTemp);
stMSG.csContent=wpTemp;
caRevevieMSG.Add(stMSG);
free(pszTemp);
free(wpTemp);
}
char szLog[128];
sprintf(szLog,"RecevieMSG 接收到%d条短信(解析后)。",caRevevieMSG.GetCount());
return WEBS_RET_OK;
}
3.gSplit(CString &source, CStringArray& dest, CString division)
void CWebInterface::gSplit(CString &source, CStringArray& dest, CString division)
{
dest.RemoveAll();
int pos = 0;
int pre_pos = 0;
while( -1 != pos ){
pre_pos = pos;
pos = source.Find(division,(pos+1));
if(-1==pos)
{
dest.Add(source.Mid(pre_pos,source.GetLength()));
break;
}
dest.Add(source.Mid(pre_pos,(pos-pre_pos)));
}
}
4.UnicodeToANSI( const wchar_t *str )
char * CWebInterface::UnicodeToANSI( const wchar_t *str )//直接用WideCharToMultiByte一次不支持中文
{
char * result;
int textlen;
// wide char to multi char
textlen = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
result =(char *)malloc((textlen+1)*sizeof(char));
memset( result, 0, sizeof(char) * ( textlen + 1 ) );
WideCharToMultiByte( CP_ACP, 0, str, -1, result, textlen, NULL, NULL );
return result;
}
5.ANSIToUnicode( const char* str )
wchar_t * CWebInterface::ANSIToUnicode( const char* str ) //直接用MultiByteToWideChar一次不支持中文
{
int textlen ;
wchar_t * result;
textlen = MultiByteToWideChar( CP_ACP, 0, str,-1, NULL,0 );
result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));
memset(result,0,(textlen+1)*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0,str,-1,(LPWSTR)result,textlen );
return result;
}
6.UrlDecode(char *pScrBuf, int nLen)
int CWebInterface::UrlDecode(char *pScrBuf, int nLen)
{
char *pDest = pScrBuf;
char *pData = pScrBuf;
int nValue;
int nTemp;
while (nLen--) {
if (*pData == '+') {
*pDest = ' ';
}
else if (*pData == '%' && nLen >= 2 && isxdigit((int) *(pData + 1))
&& isxdigit((int) *(pData + 2)))
{
nTemp = ((unsigned char *)(pData+1))[0];
if (isupper(nTemp))
nTemp = tolower(nTemp);
nValue = (nTemp >= '0' && nTemp <= '9' ? nTemp - '0' : nTemp - 'a' + 10) * 16;
nTemp = ((unsigned char *)(pData+1))[1];
if (isupper(nTemp))
nTemp = tolower(nTemp);
nValue += nTemp >= '0' && nTemp <= '9' ? nTemp - '0' : nTemp - 'a' + 10;
*pDest = (char)nValue ;
pData += 2;
nLen -= 2;
} else {
*pDest = *pData;
}
pData++;
pDest++;
}
*pDest = '\0';
return pDest - pScrBuf;
}
三、C#短信回复示例代码
1.获取回复网页代码.htm
<form id="form_Receive" method="post" runat="server">
<a href="mo.aspx?args=67266896,132710,18636924700,%c4%c7%c4%e3%bf%b4%bd%f0%bb%c6%bd%f0%bb%c6%b5%c4,2015-6-6 18:50:31">推过去</a>
</form>
2.获取回复网页代码mo.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="mo.aspx.cs" Inherits="mo" %>
3.获取回复实现mo.aspx.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.IO;
public partial class mo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string content = Request["args"];
if (content == null || content == "")
{
Response.Write("no data");
}
else {
record(content);
Response.Write("0");
}
}
private void record(string data)
{
string[] temp = data.Split(';');
for (int i = 0; i < temp.Length; i++)
{
//拆分
string[] temp_detail = temp[i].Split(',');
//特服号
string code = temp_detail[1];
string mobile = temp_detail[2];//手机号
// 对接收信息进行url解码
string content = HttpUtility.UrlDecode(temp_detail[3], Encoding.GetEncoding("gb2312"));//回复的内容需要解码
string stime = temp_detail[4];//用户回复的时间
string num = (i + 1).ToString();
string path = Server.MapPath("data") + "\\data.txt";
FileInfo f = new FileInfo(path);
if(!f.Exists)
{
FileStream fs= f.Create();
fs.Close();
}
StreamWriter sw = new StreamWriter(path,true);
sw.WriteLine("第" + num + "条\r");
sw.WriteLine("特服号:" + code + "\r");
sw.WriteLine("手机号:" + mobile + "\r");
sw.WriteLine("回复内容:" + content + "\r");
sw.WriteLine("回复时间:" + stime + "\r");
sw.WriteLine();
sw.Close();
}
}
}
四、webservice返回集合对照表:
返回值 | 返回值说明 | 问题描述 |
-2 | 帐号/密码不正确 | 1.序列号未注册2.密码加密不正确3.密码已被修改4.序列号已注销 |
-4 | 余额不足支持本次发送(或者修改密码长度不正确) | 余额不足(或者修改密码长度不在6位到10位之间) |
-5 | 数据格式错误 | 只能自行调试了。或与技术支持联系 |
-6 | 参数有误 | 看参数传的是否均正常,请调试程序查看各参数 |
-7 | 权限受限 | 该序列号是否已经开通了调用该方法的权限 |
-8 | 流量控制错误 | |
-9 | 扩展码权限错误 | 该序列号是否已经开通了扩展子号的权限,把ext这个参数置空。 |
-10 | 内容长度长 | 单字节不能超过1000个字符,双字节不能超过500个字符 |
-11 | 内部数据库错误 | |
-12 | 序列号状态错误 | 序列号是否被禁用 |
-14 | 服务器写文件失败 | |
-17 | 没有权限 | 如发送彩信仅限于SDK3 |
-19 | 禁止同时使用多个接口地址 | 每个序列号提交只能使用一个接口地址 |
-20 | 相同手机号,相同内容重复提交 | |
-22 | Ip鉴权失败 | 提交的IP不是所绑定的IP |
-23 | 缓存无此序列号信息 | |
-601 | 序列号为空,参数错误 | |
-602 | 序列号格式错误,参数错误 | |
-603 | 密码为空,参数错误 | |
-604 | 手机号码为空,参数错误 | |
-605 | 内容为空,参数错误 | |
-606 | ext长度大于9,参数错误 | |
-607 | 参数错误 扩展码非数字 | |
-608 | 参数错误 定时时间非日期格式 | |
-609 | rrid长度大于18,参数错误 | |
-610 | 参数错误 rrid非数字 | |
-611 | 参数错误 内容编码不符合规范 | |
-623 | 手机个数与内容个数不匹配 | |
-624 | 扩展个数与手机个数数 | |
-644 | rrid个数与手机个数不一致 |
注:以上返回值针对个别方法.请具体参看每个用到方法的详细说明。
五、附加说明:
1.接口地址:
常用接口地址:http://sdk.entinfo.cn:8060/webservice.asmx (一般调用)
多线程接口地址:http://sdk.entinfo.cn:8061/webservice.asmx (java、andriod使用)
2.其它说明:
(1)开发使用的帐号必须为SDK开头,如SDK-SSD-010-00001,帐号第一次需要调用Register方法注册一次.仅需注册一次即可,信息必须真实
(2)UnRegister与Register配合使用, 连续使用不得超过10次/天;
(3)群发推荐使用接口方法 mt或者mdSmsSend (仅方法名不同);
3. 郑重声明:
(1)禁止相同的内容多个手机号连续一条一条提交. 否则禁用帐号,由此带来损失由客户自行负责.
(2)请客户提供外网服务器IP以便于绑定IP发送,提高账号的安全性!
(3)在程序里最好有配置文件,程序自动判断当某个接口连接超时提交速度变慢时.程序可以自动切换其它的接口以下是推荐的几个服务器,仅接口地址不同而已.方法全部相同;
地址1:http://sdk.entinfo.cn:8060/webservice.asmx
地址2:http://sdk2.entinfo.cn:8060/webservice.asmx
这些地址都是标准的webservice地址,C#,Java客户可以按照自己熟悉的方式去解析String
或者
地址1:http://sdk.entinfo.cn:8060/webservice.asmx?wsdl
地址2:http://sdk2.entinfo.cn:8060/webservice.asmx?wsdl
六、示例Demo源代码下载:
C#短信回复Demo及技术文档 SDK通用版接口文档 所有下载