1

このエラーが発生した理由

    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クライアントを作成しています..数時間は機能しますが、エラーが発生します..問い合わせリンクを送信しようとすると、作成するセッションが同期され、タイプが接続のはトランシーバーですここに私がバインドしてリンクを問い合わせるために使用したコードの一部があります

   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秒ごとに問い合わせリンクに電話しました

4

1 に答える 1

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
            }
        }
}

enquire_link、try-catch、IOException の再バインド中に同じことを行い、再試行します。再帰呼び出し中の無限ループを回避するために、クーターと最大試行回数を追加することを忘れないでください。

10 秒ごとに enquire_link する必要はありません。ほとんどのプロバイダーは、実行する必要がある頻度を通知します。標準は 10 分です。

于 2013-02-22T01:11:25.107 に答える