java.net.SocketException:Broken pipe smpp.logica库

时间:2013-02-20 14:45:12

标签: java smpp

为什么我收到此错误

    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秒打电话询问一次链接,知道原因

1 个答案:

答案 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分钟。