2017-01-11 9 views
1

私は、実行時ベースのプログラミング言語用のfastCGIインターフェイスを構築しており、Windows、Linux、UNIX環境で動作します。mod_fcgid windowsという名前のパイプ第2回以降のリクエスト

実行時に実行されるプログラムコード内でfastCGIプロトコルを実装しましたが、mod_fcgidと通信するWindowsコードに問題があります。この場合、私はfastCGI関数を公開するために事前ビルドされたdllを使用することはできませんが、そのランタイム言語からほとんどのC関数を呼び出すことができます。私はそれが別の会社に属しているようにランタイムを変更することはできません...それはPHPやPerlのような言語であると考えてください。私がしようとしているのは、fastCGIリクエストを処理するためのコードセット(dllではない)のようなdllを作成するのと同じです。多くの人が私がここで "ホイールを再発明"していると言いますが、私はfastCGIへのインターフェースを提供するために誰かの事前ビルドされたdllを使用する選択肢がありません。

私はすべてをうまく実装しており、私は最初のリクエストを受け取り、私のfastCGIインターフェイスを通してウェブページを返信することができます。私が抱えている問題は、Windowsで動作しているときに「次の」要求を処理することです。私のコードはLinux上で動作するときには大変効果的ですが、ソケットを受け入れ(read)し、処理を行うwrite()、ソケットをclose()してから再びaccept()して、すべてが完全に処理されます。

Windowsでは、mod_fcgidは名前付きパイプを使用します。コード内でGetStdHandle()を使用してstdinのハンドルを取得し、ReadFile()とWriteFile()を使用し、fastCGIプロトコルでラップされたデータがmod_fcgidに送られ、ブラウザで要求が完了するとCloseHandle )、次の要求を待つためにGetStdHandle()にループバックします。

すべてが最初のリクエストに対して完全に機能し、ブラウザは自分のcgi出力を取得します。 Linux上でソケットを使っているのと同じコードで、2番目以降のリクエストを受け取り、魅力的に動作します。

私の問題は次のとおりです。Windowsで実行すると、最初のリクエストを処理した後、mod_fcgidを取得して2番目のリクエストを送信できません。それは私の窓のプロセスを殺して終了し、代わりに新しいものを開始します。どちらが当然のことではないですか?

私はFastCGIのEndRequestのを送信し、周りに私はループで来て次の要求を待機する時間の間に何か間違ったことしている必要があります。

mod_fcgidからの最初の要求を取得するには、私は(GetStdHandleを使用)私はReadFile()とWriteFile()(すべてkernel32.dllから)を使用しています。私はEndRequestでプロトコルを終了しても、2番目の要求を受け取れるようにコードを取得することはできません。

私はFileFlushBuffers()を試してみました。私はGetStdHandle()から与えられたハンドルを閉じないようにしましたが、私のWindowsアプリケーションからmod_fcgidに必要なものはわかりません。 2回目以降のリクエストを受信できます。

GetStdHandleからstdinへのハンドルを取得し、ReadFileに座っている最初の要求の後、ReadFile()は0バイトに戻り、GetLastError()は常に6(Invalid Handle)を返します。

最初のリクエストが完了した後にクリーンアップに使用するC関数を特定できず、Windowsで実行中に次のリクエストが来るのを待つことができません。私が前に言ったように、コードは名前付きパイプであるSTDINのハンドルを使用しているWindowsの代わりにソケットを使用するときにLinux上で完璧に動作します。

+0

つまり、_un_namedというパイプを使用していますか?これは 'STDIN/STDOUT'が使われるときに私が期待するものです。 – Ctx

+0

これを確認するための文書は見つかりませんでしたが、FastCGIプロトコルがTCP/IP上でどのように動作するかに基づいて、指定されたハンドルは名前付きパイプの*サーバー側にあります。 (私の以前のコメントは、クライアントの最後であると仮定していたので、私の間違いです。)ハンドルを閉じる代わりに、DisconnectNamedPipeの後にConnectNamedPipe(新しいリクエストが準備できるまでブロックされます)を呼び出します。 –

+0

ハリー、ありがとう。 NamedPipe関数を使う必要があると思います。私は人々が自分のアプリケーションに含めることができるlibfcgi.dllを含むmod_fcgiのソースを流してきました。私はConnectNamedPipeとDisconnectNamedPipeを使用してそれを参照してください。また、IOCompletionを使用していますが、実際に使用されているものはわかりませんが、NamedPipe呼び出しについてのあなたの権利を信じています。ありがとう。 – user7405204

答えて

1

ハリー、NamedPipe関数の使用についてのあなたのコメントは、私がFileFlushBuffersを使用し、最初のリクエストの最後にDisconnectNamedPipeを使用し、次にConnectNamedPipeを使用して次のリクエストが来るのを待つ必要がありました。ありがとう再び。

関連する問題