现在是我们的程序做SMPP的服务器,网关连接我方。在连接成功,并BIND后。我方用OUTPUTSTREAM数据流格式向网关发送短消息后,(强制使线程等待了10秒)手机已经接到短消息。但我使用BIND链路的INPUTSTREAM去接收返回状态的数据,竟然出现Connection Reset的错误。
估计原因是OUTPUTSTREAM的阻塞状态仍未结束。(但我信息明明已经发完了,手机都已经收到了)
请问 这是怎么回事啊?改如何解决啊。都已经郁闷好几天了。
另外请问下 该如何监听socket的阻塞状态啊?穷人,求求大家帮帮忙吧
估计原因是OUTPUTSTREAM的阻塞状态仍未结束。(但我信息明明已经发完了,手机都已经收到了)
请问 这是怎么回事啊?改如何解决啊。都已经郁闷好几天了。
另外请问下 该如何监听socket的阻塞状态啊?穷人,求求大家帮帮忙吧
解决方案 »
- 求助,java.lang.NoClassDefFoundError错误?
- 如何把inputStream读入的值转换为byte数组
- 菜鸟弱弱的提个基础问题 编译时出错 不知道怎么修改
- 急求助不能在指定文件夹内建立文件
- 关于返回ResultSet的方法的问题
- 菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜鸟程序!!!!
- 最快求一算法!
- Kosling每日提问之2004.03.17!望高手指点!
- 哪里能下到ORACLE9i的jdbc驱动?
- 我安装了Visual Age For Java 3.53 企业版,但是无法使用帮助,为什么???
- 关于 java -jar sendmsg.jar 问题
- 广度优先搜索怎么保存搜索的路径?
int j = 0;
byte abyte0[] = new byte[i];
try {
int k;
for (; j < i; j += k)
if ((k = in.read(abyte0, j, i - j)) == -1)////出错 Connection Reset
throw new IOException("SMSC Connection closed (remotely)");
return abyte0;
} catch (IOException ioexception) {
log("Read error " + ioexception.getMessage());
throw ioexception;
}
}public smppHeader getSendResult(){
smppHeader smppheader=null;
try {
byte[] ir=null;
ir=read(16);//出错 Connection Reset
log.info("返回消息=="+new String(ir));
In_ReadToString irt=new In_ReadToString(ir);
PDUHeader pdu=irt.getSmppHeader();
smppheader=new smppHeader();
smppheader.command=pdu.getCommandId();
smppheader.length=pdu.getCommandLength();
smppheader.sequence=pdu.getSequenceNumber();
smppheader.status=pdu.getCommandStatus();
} catch (decoderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
//getSendResult();
closed();
e.printStackTrace();
}finally{
return smppheader;
}
} public void sendMessages(Message message) throws Exception {
smppEncoder smppencoder1 = new smppEncoder();
smppencoder1.submit(message);
smppHeader smppheader = new smppHeader();
log.info("发送信息:"+message.DubugtoString());
smppheader.command = 5;
smppheader.sequence = message.seq;
smppheader.status = 0;
smppheader.length = 16 + smppencoder1.getBytes().length;
smppEncoder smppencoder = new smppEncoder();
smppencoder.smppHeader(smppheader);
log("isBound="+s.isBound());
//DataOutputStream pout=new DataOutputStream(out);
out.write(smppencoder.getBytes(),0,16);
out.write(smppencoder1.getBytes(),0,smppencoder1.getBytes().length);
log("length1="+smppencoder.getBytes().length);//16
log("length2="+smppencoder1.getBytes().length);//109
out.flush(); //信息不会立即发送完 可能是字节比较多 字节编码方式是UCS2
//out.close();
//s.close();
log("send message"+message.seq);
} public SmppSendMess(int i) throws Exception {
ss = new ServerSocket(i);
this.log = Appmain.getLog(); } public boolean start() throws Exception {
boolean flag = false;
int i = 0x989680;
log("Started, ready to accept");
do {
flag=false;
s = ss.accept();
s.setKeepAlive(true);
s.setTcpNoDelay(true);
log.info("客户端地址==" + s.getInetAddress().getHostAddress());
out = s.getOutputStream();
in = s.getInputStream();//省略了下面的业务判断
flag=TRUE;
}WHILE(!flag)
return flag; }
public static void main(String[] args){ SmppSendMess smppSubmit = new SmppSendMess(5018);
boolean isc=false;
while(!isc){
isc=smppSubmit.start();
}
int count=0;
getSendMess getmess = new getSendMess();
sendList = getmess.getMess();
for(int i=0;i<sendList.size();i++){
Message mess=(Message) sendList.get(i);
smppSubmit.sendMessages(mess);
sleep(10000);
this.wait(10000);
smppHeader sh = smppSubmit.getSendResult();
if (sh != null) {
log.info("第"+i+"条信息,发送结果=Sequence " + sh.sequence
+ "- length " + sh.length + "- command "
+ sh.command + "- status " + sh.status);
}
int x=getmess.update(mess);
count+=x;
}
if(count>0)
log.info("数据更新="+count+"条");
smppSubmit.closed();
}
}
你在下发短信的时候,细节上应该是向IO写一个Request和从IO读一个Response。
但是,如果,你想知道下发短信后,短信是否被手机接收。
那应该是,等短信被手机接收后,对端网关会向你发送一个状态报告信息(Report)。
这个状态报告信息,和,下发短信,使用的不是同一个Socket。
哦 不是同一个SOCKET?
谢谢了 我去问问
当程序要接收信息的时候,充当服务端。所以,要想完成和移动网关的对接,你的程序应该会有 服务端功能的代码和客户端功能的代码。我们向手机用户发送短信的方向,一般称为MT。手机用户向我们发送短信的方向,一般称为MO。发送方发送一个消息,具体过程会分成两步,发送Request和接收Response。(例如:下发给手机一条短信)
接收方接收一个消息,具体过程也会分两步,接收Request和响应Response。(例如:接收手机的一条短信)一般情况下,收发消息的程序中,用户上行的MO消息 和 描述下行MT短信状态的Report消息,是不做严格意义上的区分的。
只是在处理业务逻辑的过程中,会针对不同的上行信息进行区分处理。 所以,楼主的发送程序,在发送Request之后,不用强制线程等待,可以直接接收对应的Response,
这个Response只是告诉你,对方已经接收了你的下发内容,但,是否被手机收到,就不知道了。
当下行短消息被处理完成后(例如:手机收到短信),移动网关会向你发送一个Report信息,来报告刚才下发的短消息被成功处理。
中兴做的网关上面,CMPP\SGIP协议都是建立两条链路,即收发链路
而SMGP和SMPP都是一条链路。
具体的我也不是很清楚,还是再去问问。
谢谢诸位兄弟提醒了
这个Response只是告诉你,对方已经接收了你的下发内容,但,是否被手机收到,就不知道了。
当下行短消息被处理完成后(例如:手机收到短信),移动网关会向你发送一个Report信息,来报告刚才下发的短消息被成功处理。
很谢谢。
但我们发移动还要走中间网关。
朋友,首先SMGP MO MT都公用同一个通道,但是SMPP 可以是bind_transmitter(发送) bind_receiver(接收) bind_transceiver(收发) 可以是同一个连接完成收发,也可以两个连接 SMPP是SMGP的增强版 SMGP是把MT是把消息发给网关 手机是否收到消息SMPP完全可以知道 通过SMPP协议可以实现短信回执。你可以去看看SMPP3.4 和SMGP3.0对比下。
总结一下,一般连接重置会有如下原因导致:
1.你的socket队列中没有空间了
2.接受者不承认在数据流接口上发送的数据
3. 抛出的异常也有可能是客户端中断连接。 当客户端中断连接的时候服务器也会抛出这个异常出来。
就是说客户端正在连接的时候 突然终止 了连接,这样,服务器端会抛出Connection reset by peer 异常出来
4是在连接断开后的读和写操作引起。
建议楼主查查自己的代码是否提前断开了socket?