飞信发送API网上有很多,但没有多少是我自己满意的。很多网站提供基于Web的API调用方式向用户提供服务,但是作为使用者我心里还是没底。我总是担心自己的密码会被某些人记录,一直想写一个自己用的PHP版本飞信发送程序。
因为本人没有任何逆向基础,同时飞信版本变化不同。从nathan在百度上发布《飞信协议分析》到现在也有3年了,且当时分析的是飞信2006版本。这中间变化太多,也使得我在写PHP版本飞信发送程序是走了很多弯路。
我曾经拜读过superli_198的《让 PHP 程序利用飞信(Fetion)发免费短信》,但是该版本使用的通讯方式目前已经不被飞信支持,且superli_198也没有做新的更新。我也下载过c.young[@]xicabin.com的Openfetion,但是该版本存在明显bug,现在也不能正常使用。无奈只能硬着头皮修改一个C# 版本的飞信发送程序。
在移植C#版本的飞信发送程序到PHP过程中,我遇到了一个关于MD5加密相关的问题,困了很多天。最后在CSDN论坛ycTIN的帮助下,问题得以解决。非常感谢ycTIN。 以下是我完成的PHP版飞信短信发送类,截止到2010年2月17日下午4点该程序一直能正常工作。技术上没有什么难度,发在这里和大家交流。
<?php
/**
*@desc 飞信短信发送类(Encoded:UTF-8)
*使用方法:$myNewFetion = new myFetion('1381111111', 'password','1382222222', '测试消息' );
*非常感谢CSDN论坛ycTIN在MD5加密部分的帮助!
*本程序未做容错处理,为防止诈骗短信乱发,程序不提供添加好友功能
*测试URL:http://i.isclab.org/tools/fetion.php
*
*程序运行条件:
*1.服务器能够访问飞信服务器nav.fetion.com.cn的443端口(https)
*2.服务器端PHP程序能够创建socket访问221.176.31.4的8080端口
*
*关键技术:
*1.CURL + SSL通讯
*2.PHP Socket编程
*3.PHP MD5函数的深入理解
*4.PHP DOM处理XML
*
*@author shadu AT foxmail DOT com /CNOS(http://bbs.ouropen.org)
*@version 2010-02-17
*@copyright 任意拷贝和修改!
**/
class myFetion{
private $mobile_no = '1381111111'; // 发送者手机号
private $fetion_no = '738713940' ; // 发送者飞信号,程序自动获取
private $fetion_pwd = 'mypassword' ; // 发送者飞信登录密码
private $cookie_file = 'cookie.txt' ; // 临时存放的cookie文件
public $SMS_RECEIVER = '1382222222' ; // 短信接收者手机号码
public $SMS_TEXT = 'sms test' ; // 短信内容,支持中文
private $NONCE = 'AAB3238922BCC25A6F606EB525FFDC56' ; // SIPC服务器返回,每次不同
private $C_NONCE = 'AAB3238922BCC25A6F606EB525FFDC56' ; // 是随机的,但是固定值也没关系
private $SSIC = '' ; // cookie中提取的变量
private $RESPONSE = '' ; // 加密后的密钥串
private $url_nav = 'https://nav.fetion.com.cn/nav/getsystemconfig.aspx' ; // 443端口获取导航信息
private $domain_fetion = 'fetion.com.cn' ; // 飞信服务器的域名
private $SIPC_PROXY = '221.176.31.4:8080'; // 8080端口飞信通讯占用
private $SSI_PROXY_SIGN_IN = 'https://uid.fetion.com.cn/ssiportal/SSIAppSignIn.aspx' ; // 登录URL
private $SSI_PROXY_SIGH_OUT = 'http://ssi.fetion.com.cn/ssiportal/SSIAppSignOut.aspx' ; // 登出URL
private $proxy_http = 'proxy.example.com:8080' ; // HTTP代理服务器地址
private $curl = NULL ;
private $socket = NULL ;
/**
*从导航网站获取信息
**/
private $REQUEST_CONFIG = "<config><user mobile-no=\"%s\" /><client type=\"PC\" version=\"2.3.0230\" platform=\"W5.1\" /><servers version=\"0\" /><service-no version=\"12\" /><parameters version=\"15\" /><hints version=\"13\" /><http-applications version=\"14\" /><client-config version=\"17\" /></config>";
/**
*使用手机号码和密码向服务器获取对应的飞信号码信息
**/
private $REQUEST_SSI_SIGN = "mobileno=%s&pwd=%s" ;
/**
*使用飞信号码向SIPC服务器注册,获取临时变量NONCE和SSIC的值
**/
private $REQUEST_SIPC_SIGN_NONCE = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 1 R\r\nL: %d\r\n\r\n%s" ;
private $REQUEST_SIPC_SIGN_NONCE_BODY = "<args><device type=\"PC\" version=\"6\" client-version=\"2.3.0230\" /><caps value=\"simple-im;im-session;temp-group\" /><events value=\"contact;permission;system-message\" /><user-info attributes=\"all\" /><presence><basic value=\"400\" desc=\"\" /></presence></args>";
/**
*使用飞信号码和加密的密码登录飞信SIPC服务器
**/
private $REQUEST_SIPC_LOGIN = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 2 R\r\nA: Digest response=\"%s\",cnonce=\"%s\"\r\nL: %d\r\n\r\n%s";
private $REQUEST_SIPC_LOGIN_BODY = "<args><device type=\"PC\" version=\"6\" client-version=\"2.3.0230\" /><caps value=\"simple-im;im-session;temp-group\" /><events value=\"contact;permission;system-message\" /><user-info attributes=\"all\" /><presence><basic value=\"400\" desc=\"\" /></presence></args>";
private $REQUEST_SIPC_SENDSMS = "M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: tel:%s\r\nN: SendSMS\r\nL: %d\r\n\r\n%s";
private $REQUEST_SIPC_LOGOUT = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n";
/**
*@param $sender 短信发送者手机号
*@param $passwd 短信发送者密码
*@param $receiver 短信接收者手机号
*@param $msg 短信内容
**/
public function __construct($sender, $passwd, $receiver, $msg){
$this->mobile_no = $sender ;
$this->fetion_pwd = $passwd;
$this->SMS_RECEIVER = $receiver;
$this->SMS_TEXT = $msg;
$this->cookie_file = $this->mobile_no . $this->cookie_file ;
file_put_contents($this->cookie_file, '') ;
$this->FetionGetConfig(); // 从导航网站443端口获取登录信息
$this->FetionSocektInit(); // 初始化到SIPC的8080端口socket连接
$this->FetionGetSIPCNonce(); // 向服务器注册飞信号,获取关键变量值
if($this->FetionLogin()){ // 发送登录认证命令
$this->FetionSendSMS(); // 发送短信发送命令
$this->FetionLogout();
}
}
/**
*从导航地址获取配置信息
**/
private function FetionGetConfig(){
$this->REQUEST_CONFIG = sprintf($this->REQUEST_CONFIG,
$this->mobile_no);
$this->curl = curl_init();
curl_setopt($this->curl, CURLOPT_URL, $this->url_nav);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookie_file);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->curl, CURLOPT_POST, 1);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->REQUEST_CONFIG);
//curl_setopt($this->curl, CURLOPT_PROXY, $this->proxy_http); // 设置代理服务器
$xml_config = curl_exec($this->curl);
// 以下是从导航页面返回的XML里取相关信息
file_put_contents("test3.xml", $xml_config) ;
$xmlDom = new DOMDocument() ;
$xmlDom->loadXML($xml_config);
$fetion_server = $xmlDom->getElementsByTagName('servers');
$fetion_server->item(0)->getElementsByTagName('sipc-proxy')->item(0)->nodeValue;
$this->SSI_PROXY_SIGN_IN = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-in')->item(0)->nodeValue;
$this->SSI_PROXY_SIGH_OUT = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-out')->item(0)->nodeValue;
$this->SSI_PROXY_SIGN_IN;
// 以下获取手机号对应的飞信号
sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd) ;
curl_setopt($this->curl, CURLOPT_URL, $this->SSI_PROXY_SIGN_IN);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd));
$Result = curl_exec($this->curl);
curl_close($this->curl);
file_put_contents("test4.xml", $Result) ;
$xmlDom->loadXML($Result);
$uri = $xmlDom->getElementsByTagName("user")->item(0)->getAttribute("uri");
//"sip:[email protected];p=5914"
if(preg_match('/^sip:(\d+)@(\S+);.*$/', $uri, $matches)){
$this->fetion_no = $matches[1] ;
$this->domain_fetion = $matches[2] ;
}
}
/**
*初始化Fetion通讯Socket
**/
private function FetionSocektInit(){
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
list($ip_fetion, $port_fetion) = split(':', $this->SIPC_PROXY) ; // "221.176.31.4:8080"
socket_connect($this->socket, $ip_fetion, $port_fetion) ;
}
/**
*注册飞信号码并获取临时变量NONCE和SSIC
**/
private function FetionGetSIPCNonce(){
$REQUEST_SIPC_SIGN_NONCE = sprintf($this->REQUEST_SIPC_SIGN_NONCE, $this->domain_fetion,
$this->fetion_no, strlen($this->REQUEST_SIPC_SIGN_NONCE_BODY),
$this->REQUEST_SIPC_SIGN_NONCE_BODY) ;
$sock_data = socket_write($this->socket, $REQUEST_SIPC_SIGN_NONCE);
$buf = '' ;
if (false == ($buf = socket_read($this->socket, 1000))) {
echo "Line:" . __LINE__ . "socket_read() failed; reason: " . socket_strerror(socket_last_error($this->socket)) . "\n";
}
$regex_ssic = '/.*nonce=\"(\\w+)\".*/s' ;
if(!preg_match($regex_ssic, $buf, $matches)){
echo "Fetion Error: No nonce found in socket\n";
}
$this->NONCE = strtoupper(trim($matches[1])); $regex_ssic = '/ssic\s+(.*)/s';
if (!preg_match($regex_ssic, file_get_contents($this->cookie_file), $matches)) {
echo "Fetion Error: No ssic found in cookie\n";
}
$this->SSIC = trim($matches[1]);
}
因为本人没有任何逆向基础,同时飞信版本变化不同。从nathan在百度上发布《飞信协议分析》到现在也有3年了,且当时分析的是飞信2006版本。这中间变化太多,也使得我在写PHP版本飞信发送程序是走了很多弯路。
我曾经拜读过superli_198的《让 PHP 程序利用飞信(Fetion)发免费短信》,但是该版本使用的通讯方式目前已经不被飞信支持,且superli_198也没有做新的更新。我也下载过c.young[@]xicabin.com的Openfetion,但是该版本存在明显bug,现在也不能正常使用。无奈只能硬着头皮修改一个C# 版本的飞信发送程序。
在移植C#版本的飞信发送程序到PHP过程中,我遇到了一个关于MD5加密相关的问题,困了很多天。最后在CSDN论坛ycTIN的帮助下,问题得以解决。非常感谢ycTIN。 以下是我完成的PHP版飞信短信发送类,截止到2010年2月17日下午4点该程序一直能正常工作。技术上没有什么难度,发在这里和大家交流。
<?php
/**
*@desc 飞信短信发送类(Encoded:UTF-8)
*使用方法:$myNewFetion = new myFetion('1381111111', 'password','1382222222', '测试消息' );
*非常感谢CSDN论坛ycTIN在MD5加密部分的帮助!
*本程序未做容错处理,为防止诈骗短信乱发,程序不提供添加好友功能
*测试URL:http://i.isclab.org/tools/fetion.php
*
*程序运行条件:
*1.服务器能够访问飞信服务器nav.fetion.com.cn的443端口(https)
*2.服务器端PHP程序能够创建socket访问221.176.31.4的8080端口
*
*关键技术:
*1.CURL + SSL通讯
*2.PHP Socket编程
*3.PHP MD5函数的深入理解
*4.PHP DOM处理XML
*
*@author shadu AT foxmail DOT com /CNOS(http://bbs.ouropen.org)
*@version 2010-02-17
*@copyright 任意拷贝和修改!
**/
class myFetion{
private $mobile_no = '1381111111'; // 发送者手机号
private $fetion_no = '738713940' ; // 发送者飞信号,程序自动获取
private $fetion_pwd = 'mypassword' ; // 发送者飞信登录密码
private $cookie_file = 'cookie.txt' ; // 临时存放的cookie文件
public $SMS_RECEIVER = '1382222222' ; // 短信接收者手机号码
public $SMS_TEXT = 'sms test' ; // 短信内容,支持中文
private $NONCE = 'AAB3238922BCC25A6F606EB525FFDC56' ; // SIPC服务器返回,每次不同
private $C_NONCE = 'AAB3238922BCC25A6F606EB525FFDC56' ; // 是随机的,但是固定值也没关系
private $SSIC = '' ; // cookie中提取的变量
private $RESPONSE = '' ; // 加密后的密钥串
private $url_nav = 'https://nav.fetion.com.cn/nav/getsystemconfig.aspx' ; // 443端口获取导航信息
private $domain_fetion = 'fetion.com.cn' ; // 飞信服务器的域名
private $SIPC_PROXY = '221.176.31.4:8080'; // 8080端口飞信通讯占用
private $SSI_PROXY_SIGN_IN = 'https://uid.fetion.com.cn/ssiportal/SSIAppSignIn.aspx' ; // 登录URL
private $SSI_PROXY_SIGH_OUT = 'http://ssi.fetion.com.cn/ssiportal/SSIAppSignOut.aspx' ; // 登出URL
private $proxy_http = 'proxy.example.com:8080' ; // HTTP代理服务器地址
private $curl = NULL ;
private $socket = NULL ;
/**
*从导航网站获取信息
**/
private $REQUEST_CONFIG = "<config><user mobile-no=\"%s\" /><client type=\"PC\" version=\"2.3.0230\" platform=\"W5.1\" /><servers version=\"0\" /><service-no version=\"12\" /><parameters version=\"15\" /><hints version=\"13\" /><http-applications version=\"14\" /><client-config version=\"17\" /></config>";
/**
*使用手机号码和密码向服务器获取对应的飞信号码信息
**/
private $REQUEST_SSI_SIGN = "mobileno=%s&pwd=%s" ;
/**
*使用飞信号码向SIPC服务器注册,获取临时变量NONCE和SSIC的值
**/
private $REQUEST_SIPC_SIGN_NONCE = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 1 R\r\nL: %d\r\n\r\n%s" ;
private $REQUEST_SIPC_SIGN_NONCE_BODY = "<args><device type=\"PC\" version=\"6\" client-version=\"2.3.0230\" /><caps value=\"simple-im;im-session;temp-group\" /><events value=\"contact;permission;system-message\" /><user-info attributes=\"all\" /><presence><basic value=\"400\" desc=\"\" /></presence></args>";
/**
*使用飞信号码和加密的密码登录飞信SIPC服务器
**/
private $REQUEST_SIPC_LOGIN = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 2 R\r\nA: Digest response=\"%s\",cnonce=\"%s\"\r\nL: %d\r\n\r\n%s";
private $REQUEST_SIPC_LOGIN_BODY = "<args><device type=\"PC\" version=\"6\" client-version=\"2.3.0230\" /><caps value=\"simple-im;im-session;temp-group\" /><events value=\"contact;permission;system-message\" /><user-info attributes=\"all\" /><presence><basic value=\"400\" desc=\"\" /></presence></args>";
private $REQUEST_SIPC_SENDSMS = "M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: tel:%s\r\nN: SendSMS\r\nL: %d\r\n\r\n%s";
private $REQUEST_SIPC_LOGOUT = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n";
/**
*@param $sender 短信发送者手机号
*@param $passwd 短信发送者密码
*@param $receiver 短信接收者手机号
*@param $msg 短信内容
**/
public function __construct($sender, $passwd, $receiver, $msg){
$this->mobile_no = $sender ;
$this->fetion_pwd = $passwd;
$this->SMS_RECEIVER = $receiver;
$this->SMS_TEXT = $msg;
$this->cookie_file = $this->mobile_no . $this->cookie_file ;
file_put_contents($this->cookie_file, '') ;
$this->FetionGetConfig(); // 从导航网站443端口获取登录信息
$this->FetionSocektInit(); // 初始化到SIPC的8080端口socket连接
$this->FetionGetSIPCNonce(); // 向服务器注册飞信号,获取关键变量值
if($this->FetionLogin()){ // 发送登录认证命令
$this->FetionSendSMS(); // 发送短信发送命令
$this->FetionLogout();
}
}
/**
*从导航地址获取配置信息
**/
private function FetionGetConfig(){
$this->REQUEST_CONFIG = sprintf($this->REQUEST_CONFIG,
$this->mobile_no);
$this->curl = curl_init();
curl_setopt($this->curl, CURLOPT_URL, $this->url_nav);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookie_file);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->curl, CURLOPT_POST, 1);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->REQUEST_CONFIG);
//curl_setopt($this->curl, CURLOPT_PROXY, $this->proxy_http); // 设置代理服务器
$xml_config = curl_exec($this->curl);
// 以下是从导航页面返回的XML里取相关信息
file_put_contents("test3.xml", $xml_config) ;
$xmlDom = new DOMDocument() ;
$xmlDom->loadXML($xml_config);
$fetion_server = $xmlDom->getElementsByTagName('servers');
$fetion_server->item(0)->getElementsByTagName('sipc-proxy')->item(0)->nodeValue;
$this->SSI_PROXY_SIGN_IN = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-in')->item(0)->nodeValue;
$this->SSI_PROXY_SIGH_OUT = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-out')->item(0)->nodeValue;
$this->SSI_PROXY_SIGN_IN;
// 以下获取手机号对应的飞信号
sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd) ;
curl_setopt($this->curl, CURLOPT_URL, $this->SSI_PROXY_SIGN_IN);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd));
$Result = curl_exec($this->curl);
curl_close($this->curl);
file_put_contents("test4.xml", $Result) ;
$xmlDom->loadXML($Result);
$uri = $xmlDom->getElementsByTagName("user")->item(0)->getAttribute("uri");
//"sip:[email protected];p=5914"
if(preg_match('/^sip:(\d+)@(\S+);.*$/', $uri, $matches)){
$this->fetion_no = $matches[1] ;
$this->domain_fetion = $matches[2] ;
}
}
/**
*初始化Fetion通讯Socket
**/
private function FetionSocektInit(){
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
list($ip_fetion, $port_fetion) = split(':', $this->SIPC_PROXY) ; // "221.176.31.4:8080"
socket_connect($this->socket, $ip_fetion, $port_fetion) ;
}
/**
*注册飞信号码并获取临时变量NONCE和SSIC
**/
private function FetionGetSIPCNonce(){
$REQUEST_SIPC_SIGN_NONCE = sprintf($this->REQUEST_SIPC_SIGN_NONCE, $this->domain_fetion,
$this->fetion_no, strlen($this->REQUEST_SIPC_SIGN_NONCE_BODY),
$this->REQUEST_SIPC_SIGN_NONCE_BODY) ;
$sock_data = socket_write($this->socket, $REQUEST_SIPC_SIGN_NONCE);
$buf = '' ;
if (false == ($buf = socket_read($this->socket, 1000))) {
echo "Line:" . __LINE__ . "socket_read() failed; reason: " . socket_strerror(socket_last_error($this->socket)) . "\n";
}
$regex_ssic = '/.*nonce=\"(\\w+)\".*/s' ;
if(!preg_match($regex_ssic, $buf, $matches)){
echo "Fetion Error: No nonce found in socket\n";
}
$this->NONCE = strtoupper(trim($matches[1])); $regex_ssic = '/ssic\s+(.*)/s';
if (!preg_match($regex_ssic, file_get_contents($this->cookie_file), $matches)) {
echo "Fetion Error: No ssic found in cookie\n";
}
$this->SSIC = trim($matches[1]);
}
/**
*登录飞信服务器
**/
private function FetionLogin(){
$this->RESPONSE = $this->FetionEncryptPassWD() ;
$REQUEST_SIPC_LOGIN = sprintf($this->REQUEST_SIPC_LOGIN,
$this->domain_fetion, $this->fetion_no,
$this->RESPONSE, $this->C_NONCE,
strlen($this->REQUEST_SIPC_LOGIN_BODY),
$this->REQUEST_SIPC_LOGIN_BODY);
$buf = '' ;
$sock_data = socket_write($this->socket, $REQUEST_SIPC_LOGIN);
if (false == ($buf = socket_read($this->socket, 1000))) {
echo "Line:" . __LINE__ . "socket_read() failed; reason: " . socket_strerror(socket_last_error($this->socket)) . "\n";
}
if(preg_match_all('/200/s', $buf, $matches)){
return True;
}else{
return False;
}
}
/**
*发短信
**/
public function FetionSendSMS(){
//"M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: tel:%s\r\nN: SendSMS\r\nL: %d\r\n\r\n%s";
$REQUEST_SENDSMS = sprintf($this->REQUEST_SIPC_SENDSMS,
$this->domain_fetion, $this->fetion_no,
$this->SMS_RECEIVER,
strlen($this->SMS_TEXT),
$this->SMS_TEXT) ;
$buf = '' ;
$sock_data = socket_write($this->socket, $REQUEST_SENDSMS);
if (false == ($buf = socket_read($this->socket, 1000))) {
echo "\nLine:" . __LINE__ . " socket_read() failed; reason: " . socket_strerror(socket_last_error($this->socket)) . "\n";
}
if(preg_match_all('/200/s', $buf, $matches)){
return True;
}else{
return False;
}
}
/**
*登出飞信服务器
**/
private function FetionLogout(){
//string Logout = String.Format(FETION_SIPC_LOGOUT, FETION_DOMAIN_URL, Fetion_Number);
$FETION_SIPC_LOGOUT = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n";
$REQUEST_SIPC_LOGOUT = sprintf($this->REQUEST_SIPC_LOGOUT,
$this->domain_fetion,
$this->fetion_no) ;
socket_write($this->socket, $REQUEST_SIPC_LOGOUT);
socket_close($this->socket) ;
} /**
*生成加密串,感谢CSND ycTIN的帮助!
*@return string 加密的密码串 *
**/
private function FetionEncryptPassWD() {
$key = md5($this->fetion_no . ':' . $this->domain_fetion . ':' . $this->fetion_pwd, true);
$h1 = strtoupper(md5($key . ':' . $this->NONCE . ':' . $this->C_NONCE));
$h2 = "REGISTER:" . $this->fetion_no ;
$h2 = strtoupper(md5($h2));
$response = "$h1:" . $this->NONCE . ":" . $h2;
$response = strtoupper(md5($response));
return $response ;
} /**
*打印一下临时变量
**/
public function printVar(){
print "\nCNONCE:" . $this->C_NONCE;
print "\nDomain:" . $this->domain_fetion;
print "\nNONCE:" . $this->NONCE;
print "\nRESPONSE:" . $this->RESPONSE;
}
public function __destruct(){
//$this->FetionLogout() ;
@unlink($this->cookie_file); // 删除cookie文件
}
}//$myNewFetion = new myFetion('13811111111', 'password', '13822222222', '飞信测试');//$myNewFetion->printVar() ;
?>
测试用的Web程序:fetion.php
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>飞信短信PHP类测试界面</title>
</head>
<body>
<div style="margin-top:5px;margin-right:400px;">
<?php
error_reporting(0);
@require("class.fetion.php");
if(isset($_POST['sender'])){
$receiver = '' ;
$msg = '' ;
if (!is_numeric($_POST['sender'])) return ;
if (!isset($_POST['pass'])) return;
if (!isset($_POST['receiver'])) {
$receiver = $_POST['sender'] ;
}else{
$receiver = $_POST['receiver'];
}
if (!isset($_POST['msg'])) {
$msg = "短信测试--http://i.isclab.org/tools/fetion.php" ;
}else{
$msg = $_POST['msg'] ;
}
$myfetion = new myFetion($_POST['sender'], $_POST['pass'], $receiver, $msg);
echo "<div><font color=\"red\">测试短信已经发送</font></div>" ;
}
?>
<br/>
<div id="sendsms">
<form method="POST" action="fetion.php">
发送者的手机号<input name="sender" type="text" size="12" /><br/>
登录飞信的密码<input name="pass" type="password" size="13" /><br/>
接收者的手机号<input name="receiver" type="text" size="12" /><br/>
短信发送的内容<input name="msg" type="text" size="50" /><br/><br/>
<input name="send" value="发送短信" type="submit" />
</form>
</div>
<div>
<font color="red">本人申明不会记录您的密码,请在测试前三思!<br>
同时,建议测试完毕后立即修改您的飞信登录密码
</font><br/><br/>
因网站服务商禁用了php的socket功能,本站代码暂时无法测试。
请<a href="fetion.zip">下载代码</a>本地测试。
</div>
</div>
</body>
</html>
ycTIN,wuyq11,Moxie,PHP菜鸟等
另: 使用临时文件做POST xml 数据, 如果并发访问大的话,会存在冲突..
另外过程中的xml文件是调试使用的,可以把那两句注释掉。
目前处理方式是每个手机号使用一个cookie文件,用完了就删除。
就是打算给好友发,才提示
Fetion Error: No ssic found in cookie
Notice: Undefined offset: 1 in D:\PHPSERVER\htdocs\fetion.php on line 174
CNONCE:AAB3238922BCC25A6F606EB525FFDC56
Domain:fetion.com.cn
NONCE:15CF056E5A612D915B18466277A6D414
RESPONSE:11D3621E2424E50C748F683751A9B869
不能成功发送
line 174的内容是:$this->SSIC = trim($matches[1]);
给常感谢你的测试和提醒,确实存在这个问题。
我已经修改了这个bug,请参见这页面http://topic.csdn.net/u/20100303/22/2295337f-dc45-4108-813b-ffa688b11f76.html
Warning: socket_read() [function.socket-read]: unable to read from socket [0]: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 in