0

私はJavaで簡単なサーバーアプリケーションを実装しようとしています。

それが行うのは、tcp / ipのメッセージを読み取り、それを文字列として保存することだけです。これが私のコードです。

    try{
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    } catch (IOException e) {
        System.out.println("cannot open input buffer");
        System.exit(-1);
    }

    clientSocket.setSoTimeout(5000);

    //read first bit of message
    message = in.readLine();
    System.out.println(message);
    //as message is an undefined length we need to loop and check for the springer miller 
    //end mark /Request
    while(message.contains("/Request") == false  )
    {
        try {
        message = in.readLine();
        System.out.println(message);
        }
        catch (IOException e) {
            System.out.println("cannot open input buffer");
            System.exit(-1);
        }
    }       

    //reply
    out.println(outputLine);

私が抱えている問題は、メッセージにEOFが含まれていないように見えることです。それは私が私のものに翻訳している別の会社のプロトコルです、それは私がメッセージにEOFを追加することができないようにプログラムの目的です

プログラムを実行した場合に取得できる情報は次のとおりです。

POST / HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: http://htng.org/1.1/Listener.Wsdl#ReceiveMessageAsync
User-Agent: Java/1.6.0_24
Host: 192.168.0.32:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 3009

次に、メッセージ本文を読み取る必要があるときにハングします。

私はこれまでJavaを使用したことがなく、自分のEOFを検出するために読み取られたバイナリソケットを書きたくありません。

x秒間読んでから戻る方法はありますか

助けてくれてありがとう。

PSはすでにC++でプログラムを正常にビルドしていますが、宛先のマシンが不明であるため、Javaに移植する必要があります。

4

2 に答える 2

1

BufferedReader.readlineはEOFでnullを返し、例外をスローしません。

また、「他社プロトコル」はSOAPoverHTTPのようです。たぶん、HTTPまたはSOAPライブラリを使用したいですか?ここの他の人はポインタを与えることができるでしょう...

それ以外の場合は、次のアプローチを使用できます。readLineを1回実行して、メソッドが実際にPOSTであり(そうでない場合はContent-Lengthヘッダーが存在しない可能性があります)、パスが正しいかどうかを確認します。
空の行(またはnull)を返すまでreadLineを実行して、すべてのHTTPヘッダーを読み取ります。その際、Content-Lengthで始まる行を探して、次のXMLデータの長さを判別します。正しい長さのchar[]をin.read(cbuf, 0, cbuf.length)作成し、作成されたバッファーcbufにxmlを読み込むために使用します。

于 2011-03-31T16:19:03.760 に答える
0

TCP / IPの上にプロトコルを実装するのは難しいので、ネットワーク、ソケット、およびOSのI/Oがどのように機能するかをかなりよく理解する必要があります。

さらに、HTTPの実装は、ネットワークの複雑さに加えて、驚くほど複雑です。

私はあなたがおそらく深海にいることを丁寧に提案しています。あなたはこのレベルで質問をしなければならず、おそらくあなたがSOに乗ることができるよりも多くの助けが必要だからです。

...とりあえず。

読んでいるサーバーがhttpと通信しようとしている場合は、既存のコンポーネントを使用してください。おそらく良い選択であれば、ApacheHttpComponents。私はそれがhttpヘッダーを偽造することを実際には購入しません、そして私はあなたがあなたの「軽量」アプローチをスキップすることを提案します。

ここにいくつかのネットワーク-i/oの基本的な事実があります。

ネットワーク書き込みはパケット指向です。Tcp / ipは通常、すべてのパケットに可能な限り詰め込もうとします(いくつかのスマートアルゴリズムを使用)。つまり、4000バイトを書き込むと、メッセージは任意のサイズの複数のパケットに分割されますが、ネットワーク機器によっては通常1500バイト未満になります。また、1パケット未満の書き込みの場合、書き込みが1つのパケットにマージされる可能性があることも意味します。(パケットは、途中で分割およびマージすることもできます。)

ストリーム(それ自体はパケットで転送されます...)を介してメッセージを送信するには、メッセージの長さを事前に知る必要があります。または、パケット全体を読み取る(大きなバッファーに.read()を実行する)必要があります。内容を解析し、スマートな方法で完全なメッセージを抽出して構築します。まさにhttpが行うこと。(とりわけ)

TCP / IPは確かに行指向ではないため、改行は完全に無視されます。HTTPは、content-length(および常に定義されているとは限らない他のトリック)を使用して、メッセージが完全に送信されたときに閉じられる場合と閉じられない場合がある単一のtcp/ipストリームを介して「メッセージ」を送信します。

于 2011-03-31T19:13:48.657 に答える