2012-02-13 9 views
3

サーバーとして動作するJavaアプリケーションをセットアップして、Bashスクリプトからクエリを受け入れる(ブロックする)必要があります。 Javaの部分はnioを使用して書かれており、このように見えるメインループ持っている:Bashの部分が/dev/tcp/魔法に依存しているチャネルとBashとの通信:送信終了

ServerSocketChannel ssc = ...; // bound to localhost:8011 
Charset charset = ...; 

// Waits for connections forever. 
while(true) { 
    SocketChannel sc = ssc.accept(); 
    StringBuffer sb = new StringBuffer(); 
    int read = 0; 
    // Builds up a string representing the query. 
    while(true) { 
    ByteBuffer bb = ByteBuffer.allocate(1024); 
    read = sc.read(bb); 
    if(read == -1) break; 
    bb.flip(); 
    CharBuffer cb = charset.decode(bb); 
    sb.append(cb.toString()); 
    } 
    // Do something with the query. 
    sc.write(charset.encode(CharBuffer.wrap(sb.toString()))); 
    sc.close(); 
} 

を:

exec 3<> /dev/tcp/localhost/8011 
echo "message" 1>&3 

私はメッセージがバッシュから送信されていることがわかりますJavaの部分に到達します(内側のループにSystem.out.println(cb);を追加すると、その部分が見えます)が、Bashスクリプトを終了しない限り、内部ループは終了しません。

私の質問は本当に簡単です:どのようにBashスクリプトは、Javaサーバーにその通信が終了したことを知らせることができますか?私は追加しようとしました

echo -en "\004" 1>&3 

私のBashスクリプトで、しかしそれは助けになりませんでした。

+0

2番目の考えでは、チャンネルの仕組みを誤解している可能性があります。私が達成しようとしているのは、Javaが通信が今終了したと思うようにすることですが、後で再開することがあります。どういうわけか私はこれが単にチャンネルを閉じることとは別の行動でなければならないと思っていますが、それは間違っている可能性があります。私が本当に必要とするのは、「これはメッセージの終わりの様子です」という小さなプロトコルです。私にとってこれを明確にする答えも受け入れられるだろう。 – Philippe

答えて

1

ファイルディスクリプタを閉じてみます。これは、Javaによってクローズドストリームとして認識され、内部ループが終了するようにする必要があります。

exec 3>&- 

ソケットは「半開」(つまり、一方向にシャットダウンされていても、まだ開いている)ことができます。 Socketインスタンスのステータスはmethods to detectです。

bashで作成されたパイプソケットハイブリッドがこれをサポートしているかどうかはテストしていません。そうでない場合は、メッセージの境界を示すために、いくつかの内部長さエンコードまたは区切りシーケンスでプロトコルを設計する必要があります。

+0

構文をありがとう。問題は、Javaがチャンネルに書き込むことができないことです(つまり、サーバーは「クエリーで何かする」」ことはできません)。 – Philippe

+0

@Philippe試しましたか?私はそれをテストしていませんが、ソケットが "半開"(つまり、一方向にシャットダウンされていても、まだ開いている)ことができます。それがうまくいかない場合は、あなたが投稿したプロトコルが入力のシャットダウンに依存するように見えますが、出力を開いたままにしておくので、実際には別の質問(プロトコル設計について)を求める必要があります。 – erickson

+0

はい私はそれを試しました。 Java側でIOException "Broken pipe"がスローされます。私はもともと私の質問が間違っていると思っています。なぜなら、元々、 '-1'の戻りコードが' read'の意味を誤解していたからです。 – Philippe

1

私が達成しようとしているのは、Javaが の通信が現在終了していると思うようにすることですが、後で再開することがあります。

この要件は矛盾していることを理解する必要があります。通信が終了したのはまたはです。後で再開することがあります。 TCPにはこれをサポートするものは何もなく、Javaでは何も起こりません。

関連する問題