为什么我收到此错误
20:43:40,798 ERROR Tx:809 - java.net.SocketException: Broken pipe
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:109)
at com.logica.smpp.TCPIPConnection.send(TCPIPConnection.java:353)
at com.logica.smpp.Transmitter.send(Transmitter.java:79)
at com.logica.smpp.Session.send(Session.java:993)
at com.logica.smpp.Session.send(Session.java:1048)
at com.logica.smpp.Session.enquireLink(Session.java:789)
at com.logica.smpp.Tx.kirimEnquireLink(Tx.java:795)
at com.logica.smpp.Tx.access$0(Tx.java:777)
at com.logica.smpp.Tx$1.run(Tx.java:120)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
..我正在使用Open smpp logica库创建smsc客户端...几个小时它的工作但是然后错误出来..当我试图发送查询链接时,我创建的会话是同步和连接的类型是Transceiver这里是我用来绑定和enqury链接的一段代码
private void bind()
{
debug.enter(this, "SMPPTest.bind()");
try {
if (bound) {
System.out.println("Already bound, unbind first.");
return;
}
BindRequest request = null;
BindResponse response = null;
String syncMode = (asynchronous ? "a" : "s");
// type of the session
syncMode = getParam("Asynchronous/Synchronnous Session? (a/s)",
syncMode);
if (syncMode.compareToIgnoreCase("a")==0) {
asynchronous = true;
} else if (syncMode.compareToIgnoreCase("s")==0) {
asynchronous = false;
} else {
System.out.println("Invalid mode async/sync, expected a or s, got "
+ syncMode +". Operation canceled.");
return;
}
// input values
bindOption = getParam("Transmitter/Receiver/Transciever (t/r/tr)",
bindOption);
if (bindOption.compareToIgnoreCase("t")==0) {
request = new BindTransmitter();
} else if (bindOption.compareToIgnoreCase("r")==0) {
request = new BindReceiver();
} else if (bindOption.compareToIgnoreCase("tr")==0) {
request = new BindTransciever();
} else {
System.out.println("Invalid bind mode, expected t, r or tr, got " +
bindOption + ". Operation canceled.");
return;
}
ipAddress = getParam("IP address of SMSC", ipAddress);
port = getParam("Port number", port);
TCPIPConnection connection = new TCPIPConnection(ipAddress, port);
connection.setReceiveTimeout(20*1000);
session = new Session(connection);
systemId = getParam("Your system ID", systemId);
password = getParam("Your password", password);
// set values
request.setSystemId(systemId);
request.setPassword(password);
request.setSystemType(systemType);
request.setInterfaceVersion((byte)0x34);
request.setAddressRange(addressRange);
// send the request
System.out.println("Bind request " + request.debugString());
if (asynchronous) {
pduListener = new SMPPTestPDUEventListener(session);
response = session.bind(request,pduListener);
} else {
response = session.bind(request);
}
System.out.println("Bind response " + response.debugString());
if (response.getCommandStatus() == Data.ESME_ROK) {
System.out.println("CommandID "+response.getCommandId());
bound = true;
}
} catch (Exception e) {
event.write(e,"");
debug.write("Bind operation failed. " + e);
System.out.println("Bind operation failed. " + e);
} finally {
debug.exit(this);
}
}
查询链接的代码是
private void kirimEnquireLink()
{
try
{
log.info("Send enquireLink!");
EnquireLink request = new EnquireLink();
EnquireLinkResp response = new EnquireLinkResp();
// synchronized (session) {
// session.enquireLink(request);
// }
if(asynchronous)
{
session.enquireLink(request);
}else
{
response = session.enquireLink(request);
System.out.println("Enquire Link Response "+request.debugString());
}
}
catch (Exception e)
{
bound = false;
// unbind();
log.error(e, e);
}
}
我每隔10秒打电话询问一次链接,知道原因
答案 0 :(得分:1)
您面临的问题是,永远不会保证连接始终可用,也无法保证会话。许多不同的外部原因可能会导致ESME和SMSC之间的联系下降。我的建议是,尝试捕获enquire_link操作和提交操作,评估异常并采取行动。
我已经成功实现了递归方法调用来处理这个问题,如下所示
/**
* Connect to ESME and submit a message, if binding process fails, reattempt
* to reconnect and submit.
*/
public void connect() {
try {
//Create connection
BindRequest request = null;
request = new BindTransciever();
connection = new TCPIPConnection("localhost", 17632);
connection.setReceiveTimeout(20 * 1000);
session = new Session(connection);
//Prepare request
request.setSystemId("pavel");
request.setPassword("wpsd");
request.setSystemType("CMT");
request.setInterfaceVersion((byte) 0x34);
request.setAddressRange(new AddressRange());
pduListener = new SMPPTestPDUEventListener(session);
//Session binding process, if it fails, we are thrown to the catch section
//with a BrokenPipe (IOException)
session.bind(request, pduListener);
//Prepare message
SubmitSM msg = new SubmitSM();
// set values
msg.setDestAddr("04234143939");
msg.setShortMessage("hello");
msg.assignSequenceNumber(true);
//Send to our custom made submitMessage method that reattempts if failure
submitMessage(msg);
} catch (Exception ex){
//Analyze what type of exception was
if (ex instanceof IOException || ex instanceof SocketException){
//IOException relate to the brokenpipe issue you are facing
//you need to close existing sessions and connections
//restablish session
if (this.connection!=null){
this.connection.close();
}
//This is a recursive call, I encourage you to elaborate
//a little bit this method implementing a counter so you
//don't end up in an infinite loop
this.connect();
} else {
//LOG whatever other exception thrown
}
}
}
/**
* Submit message to SMSC, if it fails because of a connection issue, reattempt
* @param message
*/
private void submitMessage(SubmitSM message){
try{
session.submit(message);
} catch (Exception ex){
//Analyze what type of exception was
if (ex instanceof IOException || ex instanceof SocketException){
//IOException relate to the brokenpipe issue you are facing
//you need to close existing sessions and connections
//restablish session and try to submit again
if (this.connection!=null){
this.connection.close();
}
//Call a rebind method
this.bind();
//This is a recursive call, I encourage you to elaborate
//a little bit this method implementing a counter so you
//don't end up in an infinite loop
this.submitMessage(message);
} else {
//LOG whatever other exception thrown
}
}
}
在IOException重新绑定和重新尝试期间,对enquire_link,try-catch执行相同的操作。不要忘记添加一个couter和最大数量的尝试,以避免在递归调用期间无限循环。
您不需要每10秒钟查询一次。大多数提供商会告诉您需要完成的频率,标准是10分钟。