0

私はネットワークプログラミングの専門家ではありません。基本的に、タイムアウトが異なる2種類のクライアントがあります。クライアント/サーバー通信には、接続されたソケットでUDPを使用することになっています。

問題は2つあります。

a)クライアント(またはソケット)がt1秒間応答しない場合は、死亡としてマークする必要があります。read_fd_set内のどのソケットにもタイムアウト値内に読み取るものがない場合、selectを使用するとタイムアウトになります。では、かなり長い間読み取るデータがない1つのソケットをタイムアウトするにはどうすればよいですか?

  • 現在、selectが戻るたびに、私自身、どのソケットが応答しているか、どのソケットが応答していないかを追跡しています。そして、各クライアント(ソケット)の個々の経過時間にt1.tu_secを追加します。次に、手動で閉じて、(n)*(t1.tu_sec)時間応答しないソケットをFD_SETから除外します。これは十分なアプローチですか?

b)主な問題は、タイムアウトが異なる2種類のクライアント、t1とt2があることです。これをどのように処理しますか?

  • 同じループ内の2種類のクライアントに対して2つのselect()を使用できますか?スレッドなしで飢餓を引き起こすでしょうか?この場合、スレッドを使用することをお勧めしますか(または必須ですか)?

私は何年もの間ウェブを歩き回っています!

どんな助けでも大歓迎です。

4

3 に答える 3

1

これは非常に一般的なパターンの特殊なケースであり、選択/ポーリングループがタイマーのコレクションに関連付けられています。

次の(絶対)起動時間に順序付けられたタスクの優先キューを使用できます。選択タイムアウトは常に、キューの先頭にある絶対時間です。

  • selectがタイムアウトしたとき(そして次の反復の直前、タスクの完了に時間がかかる場合)、現在の時刻を取得し、すでに実行されているはずのすべてのタスクをキューから取り出して実行します
  • (一部の)タスクは再スケジュールする必要があるため、これを行う間、タスクが優先キューを変更できることを確認してください

次に、ロジックは簡単です。

  • 読み取り時に、ソケットをビジーとマークします
  • タイマーの実行時に、ソケットをアイドル状態としてマークします
    • すでにアイドル状態だった場合は、最後のタイマーの有効期限が切れてから何も受信されなかったことを意味します。つまり、デッドです。
于 2012-09-26T12:37:26.243 に答える
1

私の頭に浮かぶ簡単な解決策は、コレクション内のソケットを、最も近いタイムアウトまでの残り時間でソートしておくことです。

タイムアウトを残りの最小時間に設定して使用selectし、タイムアウトしたソケットをコレクションから削除/クローズ/削除して、繰り返します。

したがって、擬似コードでは次のようになります。

C = collection of structs ( socket, timeout, time_remaining := timeout )

while (true) {
    sort_the_collection_by_time_remaining
    next_timeout = min(time_remaining in C)
    select ( sockets in C, next_timeout )
    update_all_time_remaining_values
    remove_from_C_if_required  //if timeout occured
}
于 2012-09-26T11:06:37.123 に答える
0

select1回の呼び出しで簡単に解決できます。ソケットごとに、タイムアウトに関連する2つの値があります。実際のタイムアウト。そして、タイムアウトまでの時間。次に、0.1秒(または同様)ごとに「タイムアウトまでの時間」をカウントダウンし、ゼロに達したらソケットを閉じます。ソケットがタイムアウト前にトラフィックを受信した場合は、「タイムアウトまでの時間」をタイムアウト値にリセットし、ダウンカウントを再開します。

于 2012-09-26T11:05:27.267 に答える