RTSPプロトコルは、ライブおよびオンデマンド形式の再生、オーディオとビデオのストリーミングを実現することができ、ストリーミングプロトコルです。RTSPプロトコルは、サーバのさまざまな定義 - クライアントのインターフェース間の相互作用を、OPTIONS、DESCRIBE、SETUP、PLAY、TEARDOWN、RECORDがあり、発表しました。ネットワーク上のRTSPプロトコルのために書かれている多くの、私はあまりここに紹介する準備ができていませんよ。RTSPは、特定のデータの送信が含まれていない、この機能は、一般的にRTPとRTCPプロトコルによって実現され、下層のTCPまたはUDPトランスポート・モードの2つの種類によって実行することができます。
この図は、典型的なRTSPライブプロセス・サーバーである - クライアントの主な相互作用のプロセス:
EasyRTSPServerはの閉塞につながる問題の異常な部分を落としEasyRTSPServerクライアントについてのあなたと共有するためのインターフェイスは非常にシンプルで洗練されたコールである今日、安定した、効率的で、信頼性の高い、マルチプラットフォームのサポートRTSP-Serverのコンポーネントです
質問をします:
クライアントが異常であるため、Linux環境でのEasyRTSPServerは今でもアクセスすることができない、いくつかのチャンネルで、その結果、削除されます。
問題の分析:
分析サーバーは、デバッグプロセスでCLOSE_WAITがあったが、閉塞、イベントLive555ではコールフローを慎重に分析を発見した可能性があり、我々は限り、データがクライアントから受信されると、それはGenericMediaServer :: ClientSessionの:: noteLivenessが実行されますことを発見しました()関数は、イベントの最後のタイムアウトを削除し、その後、スケジューラキューにタイムアウトイベントを作成し、クライアントが突然に、通常、この作業にClientSessionのを削除し、タイムアウトタスクを呼ぶだろう、落下しましたクライアント接続の数が多い(128)の場合は、突然ソケットが解除できない導いたタイムアウトイベントにノー呼び出し、その結果、そこにブロックされる可能性がある、落ちました。
新しいタスクのタイムアウトを作成するタスクのタイムアウトの破壊
void GenericMediaServer::ClientSession::noteLiveness() {
if (fOurServerMediaSession != NULL) fOurServerMediaSession->noteLiveness();
if (fOurServer.fReclamationSeconds > 0) {
pEnvironment->taskScheduler().rescheduleDelayedTask(fLivenessCheckTask,
fOurServer.fReclamationSeconds*1000000,
(TaskFunc*)livenessTimeoutTask, this);
}
}
タイムアウトタスクは、以下を達成するために
void GenericMediaServer::ClientSession::livenessTimeoutTask(ClientSession* clientSession) {
delete clientSession;
}
プラス印刷ログのNの数は、最終的な分析のepollはソケットがのrecvfrom閉塞によって引き起こさ呼び出し、そこイベントであり、この機能では、適切なハンドラを呼び出し検出...と、突然、すぐに何SO_RCVTIMEO、案の定、Live555では内のすべてのを見つけましたコードは、そのキーワードを検索しません。
問題を解決するには:
あなたはソケットを作成した後、データを受信するためのタイムアウトを設定します。
#if defined(__WIN32__) || defined(_WIN32)
DWORD msto = (DWORD)500;
setsockopt(newSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&msto, sizeof(msto) );
setsockopt(newSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&msto, sizeof(msto) );
#else
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 500*1000;
setsockopt(newSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof tv);
setsockopt(newSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv);
#endif