1

ソケット サーバーとして Apache Camel Mina を使用してバイト ストリームを受信しようとしています。私はApache Camel 2.12.1を使用していますが、これは私の簡単なルートです:

<route id="retriever">
  <from uri="mina2:tcp://127.0.0.1:5555?sync=false" />
  <convertBodyTo type="java.lang.String" />
  <to uri="file:temp/out" />
</route>

ルートを完全に開始し、telnet を使用してデータを送信できます。私の問題は、単純な Java テスト クライアントを使用してデータを送信するときに発生します。

byte[] myData = {0x34, 0x12, 0x25, 0x34};
Socket socket = new Socket("127.0.0.1", 5555);
OutputStream os = socket.getOutputStream();
os.write(myData, 0, myData.length);
os.flush();
socket.close(); 

このクライアントを使用すると、例外はどこにも発生しませんが、データはキャメル ルートに入りません。私は独自のコーデックを実装しようとしており、MINA がデータを受信して​​いることを確認していますが、この単純なケースで特別なコーデックが必要かどうかはわかりません。バイト配列を取得して保存したいだけです。

私の質問は次のとおりです。私が間違っていることは何ですか? デフォルトの mina2 コーデックが私のシナリオで機能しないのはなぜですか? min エンドポイントにこれを許可する特別なオプションがありませんか?

ありがとう!

4

1 に答える 1

2

TextLineCodecFactory を意味する場合は、ソース コードを確認する必要があります。このコーデックのデコーダーは、区切り文字 (フレームワークが実行されている OS の改行) を使用します。

TextLineCodecFactoryTextLineDecoderLineDelimiter

デコーダーを確認してください。特にこの部分をチェック

226     private void decodeAuto(Context ctx, IoSession session, IoBuffer in, ProtocolDecoderOutput out)
227             throws CharacterCodingException, ProtocolDecoderException {
228         int matchCount = ctx.getMatchCount();
229 
230         // Try to find a match
231         int oldPos = in.position();
232         int oldLimit = in.limit();
233 
234         while (in.hasRemaining()) {
235             byte b = in.get();
236             boolean matched = false;
237 
238             switch (b) {
239             case '\r':
240                 // Might be Mac, but we don't auto-detect Mac EOL
241                 // to avoid confusion.
242                 matchCount++;
243                 break;
244 
245             case '\n':
246                 // UNIX
247                 matchCount++;
248                 matched = true;
249                 break;
250 
251             default:
252                 matchCount = 0;
253             }
254 
255             if (matched) {
256                 // Found a match.
257                 int pos = in.position();
258                 in.limit(pos);
259                 in.position(oldPos);
260 
261                 ctx.append(in);
262 
263                 in.limit(oldLimit);
264                 in.position(pos);
265 
266                 if (ctx.getOverflowPosition() == 0) {
267                     IoBuffer buf = ctx.getBuffer();
268                     buf.flip();
269                     buf.limit(buf.limit() - matchCount);
270 
271                     try {
272                         byte[] data = new byte[buf.limit()];
273                         buf.get(data);
274                         CharsetDecoder decoder = ctx.getDecoder();
275 
276                         CharBuffer buffer = decoder.decode(ByteBuffer.wrap(data));
277                         String str = new String(buffer.array());
278                         writeText(session, str, out);
279                     } finally {
280                         buf.clear();
281                     }
282                 } else {
283                     int overflowPosition = ctx.getOverflowPosition();
284                     ctx.reset();
285                     throw new RecoverableProtocolDecoderException("Line is too long: " + overflowPosition);
286                 }
287 
288                 oldPos = pos;
289                 matchCount = 0;
290             }
291         }
292 
293         // Put remainder to buf.
294         in.position(oldPos);
295         ctx.append(in);
296 
297         ctx.setMatchCount(matchCount);
298     }

そしてこの部分

180     public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
181         Context ctx = getContext(session);
182 
183         if (LineDelimiter.AUTO.equals(delimiter)) {
184             decodeAuto(ctx, session, in, out);
185         } else {
186             decodeNormal(ctx, session, in, out);
187         }
188     }

IoBuffer がいっぱいになると、新しい行が区切り文字として使用されるため、追加しないと、それを待ち続けます。これをテストしていませんが、それが問題であると確信しています。最後に改行を含む文字列を送信してみてください。それをバイトに変換して、何が起こるか見てみましょう。

データを転送したい場合は、送信機と受信機が通信の終了を設定して取得するために使用する規則を設定する、ある種のプロトコルを使用する必要があります。

于 2013-12-05T21:45:53.547 に答える