0

Java の JPOS ライブラリで作成された ISO8583 メッセージを送信しようとしています。私が行ったことは、メッセージを送信するためのソケット接続の簡単なコードを作成したことです。メッセージを正常に送信できますが、問題はサーバーが時間どおりに応答を送信することですが、メッセージがクライアント ソケットによって読み取られないことです。サーバーで強制的に接続を閉じた(手動でソケットを切断した)後にのみデータを読み取ります。

同じ接続を介して 100 を超えるメッセージを送信し、それらに対する応答を受信する必要があります。これを機能させ、サーバーが送信したときにクライアントが各メッセージをすぐに読み取れるようにするにはどうすればよいですか?

送信用のサンプルコードは次のとおりです。

logISOMsg(isoMsg);
byte[]  send_PackedRequestData = isoMsg.pack();
BufferedOutputStream outStream=null;
BufferedReader receiveStream=null;

Socket connection = new Socket("127.0.0.1", 5874);
if (connection.isConnected()) {

    outStream = new BufferedOutputStream(connection.getOutputStream());
    outStream.write(send_PackedRequestData);
    outStream.flush();
}

そして読むために:

if (connection.isConnected()) {
    receiveStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String isoMessage = receiveStream.readLine();

    ISOMsg isoMsg1 = new ISOMsg(); 
    isoMsg1.setPackager(packager);   

    byte[] bIsoMessage = new byte[isoMessage.length()];   
    for (int i = 0; i < bIsoMessage.length; i++) {
        bIsoMessage[i] = (byte) (int) isoMessage.charAt(i); 
    }                                
    isoMsg1.unpack(bIsoMessage); 

    System.out.println("MTI='"+isoMsg1.getMTI()+"'");     
    for (int i=1; i<=isoMsg1.getMaxField(); i++) {
        if (isoMsg1.hasField(i))
            System.out.println("DE : "+ i + " =  " + isoMsg1.getString(i) + "");
    }
}
4

1 に答える 1

3

受信者は、ソケットからの読み取りを停止してメッセージを返すタイミングを何らかの形で知る必要があります。これは基本的に 3 つの方法で行うことができます: メッセージの長さを固定するか、各メッセージにその長さのプレフィックスを付けるか、各メッセージを終了するターミネータ シンボルを使用します。

送信者側では、受信者がその長さを知る方法をさらに示すことなく、メッセージを送信するだけです。私は ISO8583 規格を知らないので、この形式のメッセージが上記の機能のいずれかを持っているかどうかはわかりません。

ただし、受信側でBufferedReader.readLine()は、3 番目のオプションを使用して改行を待機する を使用します。どうやらあなたのメッセージは改行で終わっていないため、リーダーは改行を待って無限にハングアップします。

メッセージは文字列ではなくバイト配列でエンコードされるため、この文字がメッセージ自体に決して出現しないことが保証されるまで、改行をターミネータ記号として使用しないでください。代わりに、そのようなメッセージを通常どのように送信するか、および受信者がメッセージの長さを知る方法を確認する必要があります。

さらに、ここではバグである文字列とバイト配列を混在させています。送信者は未加工のバイト配列を送信します。受信側では、InputStreamReader が内部でバイト配列を文字列に変換します。この操作は、UTF-8 などの文字セットを使用して、バイトを文字にデコードします。使用する文字セットを指定することさえしないため、出力はほとんど任意になる可能性があります。その後、コードは文字列をバイト配列に変換しますが、このコードは間違っており、元のコンテンツを復元することを保証していません (結果のバイト配列は、サーバーが送信したものとは異なる場合があります)。

したがって、送信側で Writer クラスを使用しない場合は、受信側で Reader クラスを使用しないでください。代わりに、送信中と同じようにストリームのみを使用してください。

于 2015-01-17T09:37:58.793 に答える