メインコンテンツへスキップ
検索

約1年半前に、OpenVOSリリース17.1でのacceptの動作方法の変更点についてのブログを書きました。この変更は、アプリケーションコードがPOSIXベースの場合にのみ有効であるということです。要約すると、17.1以前のSTCPは、サーバアプリケーションコードが acceptルーチンを呼び出した場合にのみ、クライアント接続要求に応答していました。コードが accept を呼び出さなかった場合、クライアントの接続要求はキューに入りますが、応答されることはありませんでした。アプリケーションが accept を呼び出すと、STCP は接続応答を送信します。クライアントがまだ待機している場合は、その時点で接続が完了します。クライアントがすでにあきらめていた場合は、接続応答にリセットで応答し、STCPは接続を破棄し、acceptはハング(ブロッキングモードを想定)して別の接続を待つことになります。

図1はこのシナリオを示しています。左端のテキスト行はサーバアプリケーションからのステータスメッセージであり、字下げされたpacket_monitor行(少し修正されています)はクライアントの活動の結果です。アプリケーション(acceptTestnoPosix)が起動され、ポート12345をリッスンし、一旦リッスンすると300秒間スリープ状態になります。クライアントはその後、Syn (S) フラグを設定してポート 12345 に TCP セグメントを送信し、ポート 12345 への接続を行います。これは3回トライしてからあきらめます。300 秒後にアプリケーションが起動し、accept を呼び出します。STCP スタックは、Syn および Ack (SA) フラグが設定された TCP セグメントでクライアントに応答します。リセット(R)を送信すると、クライアントは接続の記録を持たなくなるため、STCPはこの時点でブロックします。もしソケットがノンブロッキングモードであれば、ACCEPTはEAGAINエラーを返します。

acceptTestnoPosix 12345
acceptTestnoPosix 12345 の実行
300秒睡眠

  11:04:45.923 R TCP 164.152.77.50 164.152.77.217 11071 12345 S
  11:04:48.925 R TCP 164.152.77.50 164.152.77.217 11071 12345 S
  11:04:54.937 R TCP 164.152.77.50 164.152.77.217 11071 12345 S

ポート番号12345での接続を受け入れる準備ができました。
  11:09:41.852 T TCP 164.152.77.217 164.152.77.50 12345 11071 SA 
  11:09:41.854 R TCP 164.152.77.50 164.152.77.217 11071 12345 R

図1 - プリ17.1または非POSIXポスト17.1を受け入れる

 

アプリケーションがPOSIXベースの場合、状況は異なります(図2)。STCPは接続要求(S)に対して即座に応答します(SA)。その後、300秒後にアプリケーションがウェイクアップし、acceptを呼び出し、STCPは受け入れられたソケットを返します。

acceptTestwithPosix 12345
acceptTestnoPosix 12345 の実行
300秒睡眠

  10:58:43.962 R TCP 164.152.77.50 164.152.77.217 11024 12345 S
  10:58:43.964 T TCP 164.152.77.217 164.152.77.50 12345 11024 SA 
  10:58:43.964 R TCP 164.152.77.50 164.152.77.217 11024 12345 A

ポート番号12345での接続を受け入れる準備ができました。
受け入れられた接続

図2 - POSIXベースのポスト17.1を受け入れる

 

この動作の違いが重要になることがあります。接続後にクライアントがサーバアプリケーションからの応答を期待している場合、アプリケーションが実際に accept を呼び出す前にタイムアウトして接続を閉じることがあります。

POSIXでアプリケーションを構築するには?最初の一行

#define _POSIX_C_SOURCE 200112L

はアプリケーションのソースの最初の行でなければなりません。次にライブラリのパス

(master_disk)>system>posix_object_library

は、STCP ライブラリの後、C ライブラリの前のオブジェクト・ライブラリ・パスにある必要があります。

これが行われたかどうかはどうやってわかるのでしょうか?アプリケーションがバインドされているオブジェクトライブラリを見るには display_program_module -object_dirs コマンドを使います。

display_program_module acceptTestwithPosix -object_dir      
     %azvos#m17_mas>SysAdmin>Noah_Davids>temp>acceptTestwithPosix.pm 

オブジェクトディレクトリマップ。

    11の検索ディレクトリ
     0 非検索ディレクトリ
    全11件のディレクトリ

   DTCディレクトリパス

     1 %azvos#m17_mas>SysAdmin>Noah_Davids>temp
     2 %azvos#m17_mas>system>stcp>object_library
     3 %azvos#m17_mas>system>stcp>object_library>socket
     4 %azvos#m17_mas>system>stcp>object_library>net
     5 %azvos#m17_mas>system>stcp>object_library>common
     6 %azvos#m17_mas>system>posix_object_library
     7 %azvos#m17_mas>system>c_object_library
     8 %azvos#m17_mas>system>object_library
     9 %azvos#m17_mas>opt>apache>lib
    10 %azvos#m17_mas>opt>openssl>lib
    11 %azvos#m17_mas>opt>mysql>lib>mysql

しかし、これでは#defineがソースコードの一部であるかどうかはわかりません。

POSIX ベースのプログラムには SF_POSIX ソケットフラグが設定されています。例えば、私は acceptTestnoPosix、acceptTestwithPosix、acceptTestwithPosixPathOnly という 3 つのプログラムを持っています。この最後のプログラムは、ライブラリパスに >system>posix_object_library ディレクトリがありますが、ソースコードに #define が含まれていませんでした。これは無効な組み合わせとみなされることに注意してください。POSIX ライブラリにバインドされていて POSIX_SOURCE #define 文をコードに含んでいたアプリケーションだけが SF_POSIX フラグを持つソケットを作成しました。

acceptTestnoPosix.pm 12345     
acceptTestnoPosix 12345 の実行
300秒睡眠
               as: match posix; dump_stcbq -full -lport 12345     
               として。
acceptTestwithPosix.pm 12345
acceptTestnoPosix 12345 の実行
300秒睡眠
               as: match posix; dump_stcbq -full -lport 12345
                                                   SF_POSIX
               として。  
acceptTestwithPosixPathOnly.pm 12345
acceptTestnoPosix 12345 の実行
300秒睡眠
               as: match posix; dump_stcbq -full -lport 12345
               として。

4つ目の可能性としては、#defineがソースに含まれていたがposix_object_libraryが使われていなかったということが考えられます。この場合、ソケットルーチンはエラーを返します。

acceptTestwithPosixDefineOnly 12345
acceptTestnoPosix 12345 の実行
acceptTestnoPosix: リスニングソケットを作成できません。ビルドされたアプリケーション  
+ 不正確です。POSIXランタイムはCランタイムの前に検索されなければなりません。

STCPコマンドとユーティリティはすべてPOSIXで構築されており、構築するアプリケーションもPOSIXを使用することを強く推奨します。

メニューを閉じる

© 2020ストラタステクノロジー.