简体   繁体   English

java.net.SocketException:管道smpp.logica库损坏

[英]java.net.SocketException: Broken pipe smpp.logica library

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 ..我正在使用Open smpp logica库创建smsc客户端。它工作了几个小时,但随后出现了错误。.当我尝试发送查询链接时,我创建的会话是同步的,并且类型的连接是收发器这是我用来绑定和查询链接的一段代码

   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 我每10秒打电话给查询链接,不知道为什么

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. 许多不同的外部原因可能导致ESME和SMSC之间的联系下降。 My suggestion, try-catch the enquire_link operations and the submit operations, evaluate the Exception and take action. 我的建议是,尝试捕获enquire_link操作和Submit操作,评估Exception并采取措施。

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. 在IOException重新绑定和重新尝试期间,对enquire_link,try-catch进行相同的操作。 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. 您不需要每10秒一次enquire_link。 Most providers will let you know how often it needs to be done, the standard is 10 minutes. 大多数提供程序会让您知道需要执行的频率,标准是10分钟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM