why i got this error
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)
..I'm Using Open smpp logica library to create smsc client..for a few hours it's work but then the error come out..when i'm trying to send enquiry link,,the session I create is syncronize and the type of connection is Transceiver here's a piece of code i used to bind and to enqury link
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);
}
}
the code for enquiry link is
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);
}
}
i called enquiry link every 10 second,, any idea why
The problem you are facing is that there is never insurance that connection will be always available, nor the session. Many different external reasons can bring the link between ESME and SMSC down. My suggestion, try-catch the enquire_link operations and the submit operations, evaluate the Exception and take action.
I've successfully implemented recursive method calls to deal with this issue as follows
/**
* 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
}
}
}
Do the same with the enquire_link, try-catch, during IOException rebind, and reattempt. Do not forget to add a couter and a maximum ammount of attempts in order to avoid infinite loops during recursive calls.
You do not need to enquire_link every 10 seconds. Most providers will let you know how often it needs to be done, the standard is 10 minutes.