2

サーバー側のソケットに関する問題に直面しています。私のコードはクライアント側です。2番目のメッセージ(ハートビートまたはその他のメッセージ)を送信するときは常に、サーバーで失敗し、サーバー側は「メッセージ形式のエラー」をログに記録しますが、同じメッセージが最初に成功します。これを手伝ってください。私のクライアントコード:

    public class Main {

        String Host = "";
        int port = 1111;
        Socket ss;
        BufferedReader in;
        BufferedWriter out;
        String recv;

        public void connection() {
            try {

                ss = new Socket(Host, port);
                ss.setSoTimeout(30000);

                in = new BufferedReader(new InputStreamReader(ss.getInputStream()));
                out = new BufferedWriter(new OutputStreamWriter(ss.getOutputStream()));

            } catch (UnknownHostException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        public void sender(String regTag) {

            if (ss == null || !ss.isConnected()) {
                connection();
            }
            try {

                if (out != null && regTag != null) {
                    out.write(regTag + "\n");
                    System.out.println("message::" + regTag);
                    out.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public String Reciver() {

            try {

                recv = in.readLine();
                if (ss != null && recv != null) {
                    return recv;
                } else {
                    disconnect();
                    String Str = "nothing...Sorry";
                    return Str;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "Exception";
            }
        }

        public void disconnect() {
            try {
                System.out.println("socket discoonected.");
                ss.close();
                in.close();
                out.close();
                connection();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) {


            Main me = new Main();
            me.connection();
            String hbhb = "`SC`0004HBHBB7BDB7BD";
            String login = "`SC`00581.000000CRBTSRVM    00000001DLGLGN    00000002 TXBEG    LOGIN:USER=cvbs,PSWD=password   DEB2CCA8";
            String cut = "`SC`00631.000000CRBT00PPSPHS00000002DLGCON    00000003 TXBEG    CUT PPS FEE:MDN=9610023,CUTFEE=1000,REASON=1   BDB7DA88";
            me.sender(hbhb.trim());
            String str = me.Reciver();
            System.out.println("Response :::" + str);
            me.sender(login.trim());
            String str1 = me.Reciver();
            System.out.println("Response hb:::" + str1);
}

nullを受信します...毎秒メッセージで常に

サーバーサイドからのログ

[121_SERVER] 2012-05-03 14:26:37:213 [ERROR] [ServerAccptor.java:254] ->
errorCode = [UIP-80015] errorDesc = [Uip server has a exception when receiving data from the client,will remove the client,Server [adapter id=121],.]
        at com.ztesoft.zsmart.bss.uip.adapter.socket.server.ServerAccptor.listenMsg(ServerAccptor.java:252)
        at com.ztesoft.zsmart.bss.uip.adapter.socket.server.ServerAccptor.run(ServerAccptor.java:117)
Caused by: errorCode = [UIP-9102] errorDesc = []  Describing= [read client message error,will remove client.]
        at com.ztesoft.zsmart.bss.uip.adapters.socket.server.mml.MMLServerAdapter.readByteField(MMLServerAdapter.java:784)
        at com.ztesoft.zsmart.bss.uip.adapters.socket.server.mml.MMLServerAdapter.reciveWholeMsg(MMLServerAdapter.java:671) 
4

2 に答える 2

4

あなたのコードは多くの悪い習慣や誤謬を具体化しています。

  1. 例外をログに記録し、それ以外の場合は無視し、プログラムを続行させたり、「例外」を返したりするなどの奇妙なことをしています。これは不十分なプログラミングです。例外はあなたを助けるためにあります、血を隠すためにそれらをバンドエイドに適用させないでください。コードは、バンドエイドの下では自己回復しません。たとえばconnection()、スローすることを宣言してIOException、発信者に処理させる必要があります。

  2. (1)の結果として、多数のss != nullテストがあります。I / Oを実行する必要がある状態にあるべきではなく、そうなるss可能性もありますnull。繰り返しますが、正しい例外処理と伝播はこれを回避します。

  3. (1)のさらなる結果として!ss.isConnected()、接続が切断されたかどうかをこのAPIが通知するという誤った考えで、多数のテストがあります。そうではありません。Socketまだ接続しているかどうかだけがわかります。あなたのコードでは、あなたが呼んでいるようss = new Socket(...)に、あなたはそれを接続しました、さもなければあなたはまだそのコードを実行していません。呼び出しisConnected()ても価値はありません。

  4. 出力ストリームの前にソケット入力ストリームを閉じています。これは正しくありません。出力ストリームとソケット自体のみをfinallyブロックで閉じる必要があります。そうすれば、出力ストリームがフラッシュされます。入力ストリームを閉じると、ソケットと出力ストリームがフラッシュされずに閉じられます。そうしないでください。

于 2012-05-07T10:08:48.400 に答える
0

実際、正解は応答に何もない\nというMMLことです。したがって、これは機能しません。

recv = in.readLine();   

応答のメッセージヘッダー部分に示されているメッセージの長さを読み取り、その長さまで読み取る必要があります。

アップデート:

  1. コマンドに構文エラーがありMMLます。プロトコルのバージョン1.00を使用しているようですので、これは機能するサンプルです(違いを探してください)。

    `SC`00741.00CRBT    PPS     00000001DLGCON    00000004TXBEG     PPS CUT FEE:mdn=93784050910,fee=300,id=20140812165011003    F3E0ADDF
    

余分なスペース0は数字だけで埋める必要があります。それ以外の場合は、空白で埋める必要があります。

于 2014-08-17T07:50:46.067 に答える