`
sunnylocus
  • 浏览: 870737 次
  • 性别: 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
分享到:
评论
123 楼 whtyou 2013-06-12  
Executors.newSingleThreadExecutor() 这个语句虽然能自动重建线程,但是却会阻住新的连接.楼主偷懒啦,想通过一句话完成线程失败自动重建是不可能的.
122 楼 whtyou 2013-06-12  
sunnylocus 写道
xly_971223 写道
楼主赶紧发个稳定版吧
现在的版本的问题:
在服务端主动断开后线程就退出了,导致没法继续下行短信
如果能重建线程 重新连接程序会更健壮的

谢谢反馈,新版本已解决。


6.8日的版本存在严重问题,private ExecutorService exec = Executors.newSingleThreadExecutor(); 这句使上行接收变成了单线程,不能同时并发多个连接. 楼主修正一下吧.
121 楼 sunnylocus 2013-06-08  
xly_971223 写道
楼主赶紧发个稳定版吧
现在的版本的问题:
在服务端主动断开后线程就退出了,导致没法继续下行短信
如果能重建线程 重新连接程序会更健壮的

谢谢反馈,新版本已解决。
120 楼 yang_min 2013-06-04  
链接失效了啊,请检查下..
119 楼 xly_971223 2013-05-22  
楼主赶紧发个稳定版吧
现在的版本的问题:
在服务端主动断开后线程就退出了,导致没法继续下行短信
如果能重建线程 重新连接程序会更健壮的
118 楼 ghost_fly 2013-03-21  
可以发送长短信吗
117 楼 limengpig 2013-02-20  
因为有的时候,不知道什么原因socket关闭了,断开连接了,输入输出流关闭了,这个时候你原来的逻辑判断不出来,所以继续发送短信,就会出现
Exception in thread "MT-thread-0" java.lang.RuntimeException: java.net.SocketException: Connection reset

这个问题,我觉得是这样,楼主帮忙给分析一下呗。非常感谢。
116 楼 limengpig 2013-02-20  
线程会终端,有的时候会出现如下这个问题:
Exception in thread "MT-thread-0" java.lang.RuntimeException: java.net.SocketException: Connection reset

我修改了楼主代码中的一个判断,是否可行,请提供建议,非常感谢。

原代码:
if (isSendUnbind || (!socket.isConnected() && socket.isClosed())) {
// 如果连接已断开,则重新与SMG建立连接
}


我修改后:
if (isSendUnbind || (!socket.isConnected()) || socket.isClosed()
|| socket.isInputShutdown() || socket.isOutputShutdown()) {

// 如果连接已断开,则重新与SMG建立连接
}

楼主这样可以么?
115 楼 sunnylocus 2013-02-06  
daydaygo 写道
联通SGIP长短信:

请问各位通过联通短信接口开发时,你们长短信是怎么处理的呢?我所了解有下面2种:
1.本地拆分,分成多个sumbit,这样拆分成几条手机端将收到几条,坏处是手机端不方便阅读。(技术难点,汉字如何拆分?)
2.按照sgip协议在messagecontent中加入6字节协议头交给网关去处理。这种网关会根据你填写的协议头,将多条整合成一条,这样在手机端收到就是一条显示,不知有没有人做过这方面的,是否成功过?

下面是要加在submit消息messagecontent前的6字节协议头:

tp_udhiHead[0] = 0x05;// 表示剩余协议头的长度
tp_udhiHead[1] = 0x00;// 包头类型标识,固定填写0x00,表示长短信
tp_udhiHead[2] = 0x03;// 子包长度,固定填写0x03,表示后面三个字节的长度;
tp_udhiHead[3] = 0x0A;// 长消息参考号,每个SP给每个用户发送的每条参考号都应该不同,可以从0开始,每次加1,最大255,便于同一个终端对同一个SP的消息的不同的长短信进行识别
tp_udhiHead[4] = (byte) messageUCS2Count;// 本条长消息的的总消息数,从1到255,一般取值应该大于2
tp_udhiHead[5] = (byte) number;// 本条消息在长消息中的位置或序号,从1到255,第一条为1,第二条为2,最后一条等于第五字节的值。

同时还需将tp_udhi = 1;messageCoding = 8;

这个还没有研究,待春节过后回来开发,我想问题应该不大。
114 楼 daydaygo 2013-02-06  
联通SGIP长短信:

请问各位通过联通短信接口开发时,你们长短信是怎么处理的呢?我所了解有下面2种:
1.本地拆分,分成多个sumbit,这样拆分成几条手机端将收到几条,坏处是手机端不方便阅读。(技术难点,汉字如何拆分?)
2.按照sgip协议在messagecontent中加入6字节协议头交给网关去处理。这种网关会根据你填写的协议头,将多条整合成一条,这样在手机端收到就是一条显示,不知有没有人做过这方面的,是否成功过?

下面是要加在submit消息messagecontent前的6字节协议头:

tp_udhiHead[0] = 0x05;// 表示剩余协议头的长度
tp_udhiHead[1] = 0x00;// 包头类型标识,固定填写0x00,表示长短信
tp_udhiHead[2] = 0x03;// 子包长度,固定填写0x03,表示后面三个字节的长度;
tp_udhiHead[3] = 0x0A;// 长消息参考号,每个SP给每个用户发送的每条参考号都应该不同,可以从0开始,每次加1,最大255,便于同一个终端对同一个SP的消息的不同的长短信进行识别
tp_udhiHead[4] = (byte) messageUCS2Count;// 本条长消息的的总消息数,从1到255,一般取值应该大于2
tp_udhiHead[5] = (byte) number;// 本条消息在长消息中的位置或序号,从1到255,第一条为1,第二条为2,最后一条等于第五字节的值。

同时还需将tp_udhi = 1;messageCoding = 8;
113 楼 sunnylocus 2013-01-31  
whtyou007 写道
sunnylocus 写道
whtyou007 写道
有一个问题:就是一般服务器都是双IP,能否设置与SMG连接时的本机IP,以及上行侦听的绑定IP呢?

一个内网,一个外网,对吗?


都是外网IP,
双IP问题我是这样修改的(上一条粘错了)
socket = SocketFactory.getDefault().createSocket(unicomIp,unicomPort,InetAddress.getByName(spLoaclIp),0);

athlong 写道
烦楼主把下发线程经常断的问题解决一下。

现在帮一家企业调试短信平台,我会借这个机会好好排查下,优化后再放一个版本出来。
112 楼 athlong 2013-01-31  
烦楼主把下发线程经常断的问题解决一下。
111 楼 whtyou007 2013-01-30  
sunnylocus 写道
whtyou007 写道
有一个问题:就是一般服务器都是双IP,能否设置与SMG连接时的本机IP,以及上行侦听的绑定IP呢?

一个内网,一个外网,对吗?


都是外网IP,
双IP问题我是这样修改的(上一条粘错了)
socket = SocketFactory.getDefault().createSocket(unicomIp,unicomPort,InetAddress.getByName(spLoaclIp),0);
110 楼 whtyou007 2013-01-30  
sunnylocus 写道
whtyou007 写道
有一个问题:就是一般服务器都是双IP,能否设置与SMG连接时的本机IP,以及上行侦听的绑定IP呢?

一个内网,一个外网,对吗?

sunnylocus 写道
whtyou007 写道
有一个问题:就是一般服务器都是双IP,能否设置与SMG连接时的本机IP,以及上行侦听的绑定IP呢?

一个内网,一个外网,对吗?


双IP问题,我是这样修改的spsvrSocket = ServerSocketFactory.getDefault().createServerSocket(LISTEN_PORT,0,InetAddress.getByName(LISTEN_IP));
109 楼 sunnylocus 2013-01-30  
这个问题怀疑是粘包所致看了一遍代码,没有对TCP粘包的处理措施,这也是很多短信程序的一个棘手的问题.
粘包的现象就是网关会把多个上行同时提交给SP这时用简单的接收流就不能正常处理了,因为多数接收逻辑只处理了同一次接收的数据包中的第一条上行,后续的上行就忽略了.


limengpig 写道
您好,老师,现在遇到一个问题,其他同学也提过,就是短信第二次(就是连续运行两次发送短信的客户端,比如每次100条,那么第二次运行的100条就发送不出去)发送的时候就发不出去了,都在队列里排队,但是不发送了,我是用联通的模拟器测试的,不知道是程序问题还是模拟器问题,但奇怪的是不是每次都这样


我没法判断问题所在,在客户端发送完短信后,flush一下输出流试试。
108 楼 sunnylocus 2013-01-30  
whtyou007 写道
有一个问题:就是一般服务器都是双IP,能否设置与SMG连接时的本机IP,以及上行侦听的绑定IP呢?

一个内网,一个外网,对吗?
107 楼 whtyou007 2013-01-26  
这个问题怀疑是粘包所致看了一遍代码,没有对TCP粘包的处理措施,这也是很多短信程序的一个棘手的问题.
粘包的现象就是网关会把多个上行同时提交给SP这时用简单的接收流就不能正常处理了,因为多数接收逻辑只处理了同一次接收的数据包中的第一条上行,后续的上行就忽略了.


您好,老师,现在遇到一个问题,其他同学也提过,就是短信第二次(就是连续运行两次发送短信的客户端,比如每次100条,那么第二次运行的100条就发送不出去)发送的时候就发不出去了,都在队列里排队,但是不发送了,我是用联通的模拟器测试的,不知道是程序问题还是模拟器问题,但奇怪的是不是每次都这样

106 楼 whtyou007 2013-01-26  
com.tdt.unicom.sgip.svr.SPSender 中
public synchronized void sendMTReq(MTReq mtreq) throws IOException {
if (isSendUnbind || (!socket.isConnected() && socket.isClosed())) { // 如果连接已断开,则重新与SMG建立连接
此处怀疑有逻辑判断错误
缺少 判断是否正常登录到联通网关 isBind 参数的判断
会导致 没有成功Bind 就发送短信.
105 楼 whtyou007 2013-01-25  
有一个问题:就是一般服务器都是双IP,能否设置与SMG连接时的本机IP,以及上行侦听的绑定IP呢?
104 楼 limengpig 2013-01-24  
sunnylocus 写道
limengpig 写道
您好,老师,现在遇到一个问题,其他同学也提过,就是短信第二次(就是连续运行两次发送短信的客户端,比如每次100条,那么第二次运行的100条就发送不出去)发送的时候就发不出去了,都在队列里排队,但是不发送了,我是用联通的模拟器测试的,不知道是程序问题还是模拟器问题,但奇怪的是不是每次都这样


非常感谢,感谢您百忙之中给讲解一下,非常感谢。

-------------------------------------------------------------------------------------
有网友提过,应该是个bug,有空我排查下。应该是工作线程全部退出了,没有干活的线程从队列里取下发实例了。


非常感谢老师,现在好几个同学遇到了这个问题,麻烦有时间定为排查一下呗,有的时候能测试出来,有的时候测试一下午也不能重现这个bug,我连接的是模拟器。

另外,SMG向我发起的unbind请求,我这边给它回复Unbind_Resp,SMG才会关闭连接,如果我这边不回复Unbind_Resp呢,是不是SMG就不能关闭连接?也就是SMG没有收到我的Unbind_Resp,就不能擅自关闭连接?

相关推荐

Global site tag (gtag.js) - Google Analytics