`
sunnylocus
  • 浏览: 870091 次
  • 性别: Icon_minigender_1
  • 来自: 美国图森
社区版块
存档分类
最新评论

中国联通短信网关接入程序源代码(SGIP1.2协议)

    博客分类:
  • Java
阅读更多

 自从我发了博文“中国联通SP业务开发总结”后有很多的朋友问我开发上一些问题,开发接入程序必须有一定的socket编程基础,且必须熟悉sgip1.2协议才可以,我应一位网友的要求将我开发的短信接入程序源代码发布,希望对开发短信业务的朋友提供一些帮助,代码可自由传播。如有疑问请留言,我会尽量解答。

 

ps:

  lib.rar是短信程序所用到的jar包,有很多朋友问我要jar包,现在给补上。

  [lib]

    +----jdom1.1.jar

    +----log4j-1.2.16.jar

    +----mail.jar

    +----xerces.jar

 

lib里还少一个jar包,xercesImpl.jar,继续补上。

 

2011-04-15 新包发布 v1.1

修改内容:

  1. 修改com.tdt.unicom.sgip.svr.SPSender类,将计时器Timer改为ScheduledExecutorService,在测试中发现Timer内部异常时,会将错误传染给倒霉的调用者,导致下发线程全部中断。
  2. 优化了短信下发的流程。
  3. 修复了群发短信时,只有一个手机能收到短信的bug。

以上bug都是根据网友反馈发现的,在这里表示感谢。

 

 

2011-12-16 新包发布 v1.2

修改内容:

  1. 修改com.tdt.unicom.sgip.svr.SPSender类,上一个版本中,如果联通网关断开连接,SP端再次发送短信时,会出现异常,导致短信无法行,v1.2版本已修复该bug。

  感谢网友“白开水”的反馈。

 

2012-02-08 新包发布 v1.3

修改内容:

  1. 将SP的源节点编号,SMG网关的登陆用户名和密码在productionConf.xml配置文件中进行配置,无需再修改源代码的参数。

2013-06-08新包发布    v1.4

修改内容:

  1.   根据反馈,在下发线程因异常中断时,后续的短信无法再继续发送,必须重启才能  解决,该版本修复了该bug,当有线程异常退出时,自动生成的新线程替代已异常退出的线程
  2. 优化了在高并发环境下发送的策略,如果下发线程全部忙碌,采用谁调用谁发送。
  3. 预留相关接口,如果想将收到短信插入数据库,转发其它业务层等请在com.tdt.unicom.sgip.svr.UnicomSPMonitor的transmitDeliverMsg方法实现自己的业务逻辑处理。
      /**
       * 将收到的短信转发给相应的业务逻辑处理层
       * 转发方式Socket、Http、WebService
       * @param command
       */
      public void transmitDeliverMsg(final SGIPCommand command) {
    }

特别说明:

        有朋友在测试我的短信程序时,会出现Exception in thread "MT-thread-0" java.lang.RuntimeException: java.net.SocketException: Software caused connection abort: recv failed
这个异常,这是因为你测试机器的IP地址没有在联通短信平台上备案,联通SMG有一个白名单,只有你的IP地址出现在这个白名单时你才会与SMG网关建立socket连接,否则会被联通的防火墙拦截。这个异常就是因为你的socket连接被对方的防火墙给拦截了。

 

 

感谢网友“明晓”协助测试!

=====================================================================

如何打包,并加载第三方类库?

 

有童鞋下载了源代码,修改代码打好包后不知道如何加载第三方类库,下面是如如何加载第三方类库的方法。

1、在打好包(假设打好的包叫UNICOM.jar)的目录下,新建一个目录SGIP_LIB,将用到的第三方类库拷贝到该目录下

2、在打好包的目录下,新建一个目录SGIP_Config,用winrar压缩软件打开UNICOM.jar包,将所有配置文件拖到SGIP_Config目录下

3、用Winrar压缩软件打开UNICOM.jar包META-INF目录下的MANIFEST.MF文件,加入

Class-Path: ./SGIP_Config/  ./SGIP_LIB/log4j-1.2.16.jar ./SGIP_LIB/jdom1.1.jar ./SGIP_LIB/mail.jar ./SGIP_LIB/xerces.jar ./SGIP_LIB/xercesImpl.jar   

4、保存退出,在终端运行Java -jar ./UNICOM.jar即可启动短信平台(注意Class-Path未尾一定要加空格!!!)

  • UNICOM.rar (3.7 MB)
  • 描述: 过时版本
  • 下载次数: 3906
  • lib.rar (3 MB)
  • 下载次数: 1999
  • UNICOM_v1.1.rar (2.8 MB)
  • 描述: 2011-04-15 发布 新版本
  • 下载次数: 989
  • UNICOM_v1.2.rar (146.1 KB)
  • 描述: 2011-12-16 发布 v1.2
  • 下载次数: 791
  • UNICOM_v1.3.rar (154.5 KB)
  • 描述: 2012-02-08 发布 v1.3
  • 下载次数: 1190
60
6
分享到:
评论
143 楼 sunnylocus 2013-08-06  
liu19871112 写道
楼主,您好!试了好几次,文章中的附近都无法下载。
恰巧最近在进行联通短信的接入,初次接触这方面的东西,如您方便可否发一份(邮箱: 2397536042@qq.com),让我参考一下,不胜感激。

源代码已经发到你邮箱了
142 楼 liu19871112 2013-08-05  
楼主,您好!试了好几次,文章中的附近都无法下载。
恰巧最近在进行联通短信的接入,初次接触这方面的东西,如您方便可否发一份(邮箱: 2397536042@qq.com),让我参考一下,不胜感激。
141 楼 limengpig 2013-07-31  
lcogn 写道
其实下发不了短信,倒数第二个版本,确实是线程挂掉了,导致的,因为有异常没有捕获,我印象中是这样的,修改之后,从来没遇到过说,线程挂掉的问题



请哥们确认此事,如果倒数第二个版本ok,我就不改了。如果只是异常没有捕获的话。谢谢
140 楼 limengpig 2013-07-31  
sunnylocus 写道
whtyou 写道
Executors.newSingleThreadExecutor() 这个语句虽然能自动重建线程,但是却会阻住新的连接.楼主偷懒啦,想通过一句话完成线程失败自动重建是不可能的.

你没有仔细读我的源代码,Executors.newSingleThreadExecutor()是用来计算有多长时间没有向SMG发送短信了,如果超过指定时间向SMG网关发送unbind命令,断开连接。自动生成下发线程的是这个语句。
private final ThreadFactory threadFactory = new ThreadFactory() {
		int threadNo = 0;
		@Override
		public Thread newThread(Runnable task) {
			threadNo ++;
			Thread thread = new Thread(task,"MT-"+threadNo);
			thread.setUncaughtExceptionHandler(new UEHLogger());
			
			return thread;
		}
	};
    //每颗CPU分配两个线程,当有线程异常退出时,自动生成的新线程替代已异常退出的线程
	//当下发线程全部忙碌时,采用谁调用谁发送的策略
	//新生成的线程
	int threadAmount = Runtime.getRuntime().availableProcessors() * 2;
	private ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(threadAmount,threadAmount, 1000 * 30, 
			TimeUnit.SECONDS, mtReqQueue, threadFactory,new ThreadPoolExecutor.CallerRunsPolicy()); 





楼主,你真的没听清楚提问者是说在接收SMG网关发来的信息中,而不是给SMG发送信息时,请确认,期待回复,谢谢。
139 楼 limengpig 2013-07-31  
whtyou 写道
今天测试程序又发现一个问题,在用你的莎莎网关模拟器v1.2,向这个程序发送上行到800条以后这个程序会阻塞在SGIPCommand.java 的 write函数的out.write(commandBytes);这一句上.



楼主,这个问题真的还会出现?
138 楼 sunnylocus 2013-07-25  
oooodo 写道
oooodo 写道
sunnylocus 写道
oooodo 写道
sourceNode=3053191173,createTime=724161913,seqNumber=278,reportType=0,mobile=86,state=2,errorCode=102

你好,很感谢你的代码,在使用过程中,发现MT返回成功,但是手机收不到短信。
之前是可以的,但是联通那边改过一回ip,改完ip在新的服务器上就出现了这个问题,report返回102,不知道具体原因,也不知道linkID该设置成啥,目前设置成空或者sourceNode都不行,之前设置成sourceNode是可以下发成功的?
期待你的回复。


102 表示的是 SPNumber未分配或不合法,估计你没有将自己的Sp服务商号配置在文件里,在源代码有个productionConf.xml文件,将你的sp服务商号配置在spNodeid节点里


哇,竟然回复了,太感谢了。
我已经配置了,不然应该bind命令都会出错。可能刚才描述的不清楚,是submit返回0,report命令(我方为服务器时),返回102,手机收不到短信。
非常感谢


而且,我用自己的手机给该SP号码发送短信的时候,MO,delver命令式能够收到MO短信的。

还有一种解释是:你的手机没有定购产品,你需要用手机发定购命令到产品号,联通会上行Deliver命令给你,这个Deliver命令里面有个linkid,这个linkid用于标识临时的订购关系,你收到这条Deliver后,需要下行一条短信,即把收到的linkid赋值到Submit结构体中,如果不赋值这个linkid或着赋值错了,联通那边签权会不通过,手机也不会收到短信了,一旦手机用户收到了你回复的短信,那么这个用户就成功定购了你们的SP产品,以后你再向这条手机下发短信的时候就用再赋值linkid了。 源代码里有相关的例子,在TestSendSms.java里。
137 楼 oooodo 2013-07-24  
oooodo 写道
sunnylocus 写道
oooodo 写道
sourceNode=3053191173,createTime=724161913,seqNumber=278,reportType=0,mobile=86,state=2,errorCode=102

你好,很感谢你的代码,在使用过程中,发现MT返回成功,但是手机收不到短信。
之前是可以的,但是联通那边改过一回ip,改完ip在新的服务器上就出现了这个问题,report返回102,不知道具体原因,也不知道linkID该设置成啥,目前设置成空或者sourceNode都不行,之前设置成sourceNode是可以下发成功的?
期待你的回复。


102 表示的是 SPNumber未分配或不合法,估计你没有将自己的Sp服务商号配置在文件里,在源代码有个productionConf.xml文件,将你的sp服务商号配置在spNodeid节点里


哇,竟然回复了,太感谢了。
我已经配置了,不然应该bind命令都会出错。可能刚才描述的不清楚,是submit返回0,report命令(我方为服务器时),返回102,手机收不到短信。
非常感谢


而且,我用自己的手机给该SP号码发送短信的时候,MO,delver命令式能够收到MO短信的。
136 楼 oooodo 2013-07-24  
sunnylocus 写道
oooodo 写道
sourceNode=3053191173,createTime=724161913,seqNumber=278,reportType=0,mobile=86,state=2,errorCode=102

你好,很感谢你的代码,在使用过程中,发现MT返回成功,但是手机收不到短信。
之前是可以的,但是联通那边改过一回ip,改完ip在新的服务器上就出现了这个问题,report返回102,不知道具体原因,也不知道linkID该设置成啥,目前设置成空或者sourceNode都不行,之前设置成sourceNode是可以下发成功的?
期待你的回复。


102 表示的是 SPNumber未分配或不合法,估计你没有将自己的Sp服务商号配置在文件里,在源代码有个productionConf.xml文件,将你的sp服务商号配置在spNodeid节点里


哇,竟然回复了,太感谢了。
我已经配置了,不然应该bind命令都会出错。可能刚才描述的不清楚,是submit返回0,report命令(我方为服务器时),返回102,手机收不到短信。
非常感谢
135 楼 sunnylocus 2013-07-24  
oooodo 写道
sourceNode=3053191173,createTime=724161913,seqNumber=278,reportType=0,mobile=86,state=2,errorCode=102

你好,很感谢你的代码,在使用过程中,发现MT返回成功,但是手机收不到短信。
之前是可以的,但是联通那边改过一回ip,改完ip在新的服务器上就出现了这个问题,report返回102,不知道具体原因,也不知道linkID该设置成啥,目前设置成空或者sourceNode都不行,之前设置成sourceNode是可以下发成功的?
期待你的回复。


102 表示的是 SPNumber未分配或不合法,估计你没有将自己的Sp服务商号配置在文件里,在源代码有个productionConf.xml文件,将你的sp服务商号配置在spNodeid节点里
134 楼 oooodo 2013-07-24  
sourceNode=3053191173,createTime=724161913,seqNumber=278,reportType=0,mobile=86,state=2,errorCode=102

你好,很感谢你的代码,在使用过程中,发现MT返回成功,但是手机收不到短信。
之前是可以的,但是联通那边改过一回ip,改完ip在新的服务器上就出现了这个问题,report返回102,不知道具体原因,也不知道linkID该设置成啥,目前设置成空或者sourceNode都不行,之前设置成sourceNode是可以下发成功的?
期待你的回复。
133 楼 qq627955224 2013-07-15  
qushuaisheng 写道
短信下发时发生IO流异常:Connection refused: connect. 短信下发实例重新放回发送队列!

怎么回事??
132 楼 qq627955224 2013-07-11  
[Document:  No DOCTYPE declaration, Root is [Element: <gwsmip/>]]
Exception in thread "Thread-3" java.lang.NullPointerException
at java.lang.String.<init>(String.java:594)
at com.tdt.unicom.spsvr.MTReq.<init>(MTReq.java:35)
at com.tdt.unicom.spsvr.ClientReqMonitor$Handler.run(ClientReqMonitor.java:119)
at java.lang.Thread.run(Thread.java:619)
131 楼 qushuaisheng 2013-06-24  
短信下发时发生IO流异常:Connection refused: connect. 短信下发实例重新放回发送队列!
130 楼 lcogn 2013-06-21  
其实下发不了短信,倒数第二个版本,确实是线程挂掉了,导致的,因为有异常没有捕获,我印象中是这样的,修改之后,从来没遇到过说,线程挂掉的问题
129 楼 lcogn 2013-06-21  
非常感谢这篇帖子,由于工作忙的,都忘记来支持一下了,时隔半年,联通的短信早已部署,也用了2,3个月,以前的一些零碎问题,我记不太清楚,


印象最深的两个问题,

1:windows服务器下的:socketexception connection reset by peer,
2:linux服务器下的:broken pipe,

因为这两个问题,我都遇到了,我现在理解为,其实就是一个问题,只是可能,在不同的服务器下面,所描述的信息可能有差异造成的。理由其实很简单,SMG端断开了连接,我们的程序还向之前的建立连接的端口,写数据,不出问题,岂不是见鬼了?

真的非常感谢楼主的无私奉献,做开发有蛮久了,真的没有这么认真的去回一篇帖子,惭愧死了,先说到这,我去忙点别的,回头有空继续,来支持,
128 楼 Linmu719 2013-06-20  
您好,代码我下载了,关于您配置的信息能否解释下呢?我是开发联通短信接口的新手,非常感谢。我加了您QQ几次了,但是一直没有回信~~
127 楼 xly_971223 2013-06-20  
whtyou 写道
sunnylocus 写道
whtyou 写道
Executors.newSingleThreadExecutor() 这个语句虽然能自动重建线程,但是却会阻住新的连接.楼主偷懒啦,想通过一句话完成线程失败自动重建是不可能的.

你没有仔细读我的源代码,Executors.newSingleThreadExecutor()是用来计算有多长时间没有向SMG发送短信了,如果超过指定时间向SMG网关发送unbind命令,断开连接。自动生成下发线程的是这个语句。
private final ThreadFactory threadFactory = new ThreadFactory() {
		int threadNo = 0;
		@Override
		public Thread newThread(Runnable task) {
			threadNo ++;
			Thread thread = new Thread(task,"MT-"+threadNo);
			thread.setUncaughtExceptionHandler(new UEHLogger());
			
			return thread;
		}
	};
    //每颗CPU分配两个线程,当有线程异常退出时,自动生成的新线程替代已异常退出的线程
	//当下发线程全部忙碌时,采用谁调用谁发送的策略
	//新生成的线程
	int threadAmount = Runtime.getRuntime().availableProcessors() * 2;
	private ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(threadAmount,threadAmount, 1000 * 30, 
			TimeUnit.SECONDS, mtReqQueue, threadFactory,new ThreadPoolExecutor.CallerRunsPolicy()); 


可能我没说清楚,是在上行接收时使用Executors.newSingleThreadExecutor() 这个会导致上行阻塞,也就是说SMG同时只能有一个连接被响应,但一般SMG会同时建立多个连接.

你说的这个问题是楼主设计的硬伤---只有一条连接,多个线程向一条socket写数据,这样发送的速度是有限的
另外发送submit与接收submitResp是采用了同步方式,想提高发送速度的话可以采用异步方式,既一个发送submit线程与一个接收submitResp线程
126 楼 whtyou 2013-06-14  
今天测试程序又发现一个问题,在用你的莎莎网关模拟器v1.2,向这个程序发送上行到800条以后这个程序会阻塞在SGIPCommand.java 的 write函数的out.write(commandBytes);这一句上.
125 楼 whtyou 2013-06-14  
sunnylocus 写道
whtyou 写道
Executors.newSingleThreadExecutor() 这个语句虽然能自动重建线程,但是却会阻住新的连接.楼主偷懒啦,想通过一句话完成线程失败自动重建是不可能的.

你没有仔细读我的源代码,Executors.newSingleThreadExecutor()是用来计算有多长时间没有向SMG发送短信了,如果超过指定时间向SMG网关发送unbind命令,断开连接。自动生成下发线程的是这个语句。
private final ThreadFactory threadFactory = new ThreadFactory() {
		int threadNo = 0;
		@Override
		public Thread newThread(Runnable task) {
			threadNo ++;
			Thread thread = new Thread(task,"MT-"+threadNo);
			thread.setUncaughtExceptionHandler(new UEHLogger());
			
			return thread;
		}
	};
    //每颗CPU分配两个线程,当有线程异常退出时,自动生成的新线程替代已异常退出的线程
	//当下发线程全部忙碌时,采用谁调用谁发送的策略
	//新生成的线程
	int threadAmount = Runtime.getRuntime().availableProcessors() * 2;
	private ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(threadAmount,threadAmount, 1000 * 30, 
			TimeUnit.SECONDS, mtReqQueue, threadFactory,new ThreadPoolExecutor.CallerRunsPolicy()); 


可能我没说清楚,是在上行接收时使用Executors.newSingleThreadExecutor() 这个会导致上行阻塞,也就是说SMG同时只能有一个连接被响应,但一般SMG会同时建立多个连接.
124 楼 sunnylocus 2013-06-14  
whtyou 写道
Executors.newSingleThreadExecutor() 这个语句虽然能自动重建线程,但是却会阻住新的连接.楼主偷懒啦,想通过一句话完成线程失败自动重建是不可能的.

你没有仔细读我的源代码,Executors.newSingleThreadExecutor()是用来计算有多长时间没有向SMG发送短信了,如果超过指定时间向SMG网关发送unbind命令,断开连接。自动生成下发线程的是这个语句。
private final ThreadFactory threadFactory = new ThreadFactory() {
		int threadNo = 0;
		@Override
		public Thread newThread(Runnable task) {
			threadNo ++;
			Thread thread = new Thread(task,"MT-"+threadNo);
			thread.setUncaughtExceptionHandler(new UEHLogger());
			
			return thread;
		}
	};
    //每颗CPU分配两个线程,当有线程异常退出时,自动生成的新线程替代已异常退出的线程
	//当下发线程全部忙碌时,采用谁调用谁发送的策略
	//新生成的线程
	int threadAmount = Runtime.getRuntime().availableProcessors() * 2;
	private ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(threadAmount,threadAmount, 1000 * 30, 
			TimeUnit.SECONDS, mtReqQueue, threadFactory,new ThreadPoolExecutor.CallerRunsPolicy()); 

相关推荐

Global site tag (gtag.js) - Google Analytics