サーバー プログラム (ソケット ストリーム) が実行されており、クライアントを受け入れます。何らかの異常が発生したため、サーバーが終了しています。反対側のクライアントはサーバーの応答を待っています。実行中のクライアントを新しいサーバーに再接続するにはどうすればよいですか? ソケットの機能はありますか?
5 に答える
connect()
一度 edされたソケットは、への別の呼び出しで再利用できませんconnect()
。
TCP サーバーに接続してデータを読み書きする手順は次のとおりです (疑似コード)。
sd = socket(...) // create socket descriptor (allocate socket resource)
connect(sd, server-address, ...) // connect to server
read/write(sd, data) // read from server
close(sd) // close /socket descriptor (free socket resource)
サーバーがダウンした場合connect
、クライアントは次のことを行うことができ、行う必要があります。
close(sd) // close socket descriptor (free socket resource)
そして、最初からやり直します:
sd = socket(...) // create socket descriptor (allocate socket resource)
...
最初からやり直す:
connect(sd, server-address, ...) // connect to server
...
おそらく未定義の動作につながるでしょうが、少なくともエラーになります。
サーバーでこれを処理することはできませんが、クライアントのセッションを作成してから、クライアントが再接続したときに設定を復元し、メッセージの送受信を続行し、クライアント側アプリケーションで特定の間隔でスレッドを作成して、サーバーが使用可能かどうかを確認できますそうでない場合は、再接続手順を試してください。ただし、サーバー側のプログラムを確認して、プログラムがダウンするとどうなりますか?
int
connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)
{
int nsec;
/*
* Try to connect with exponential backoff.
*/
for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) {
if (connect(sockfd, addr, alen) == 0) {
/*
* Connection accepted.
*/
return(0);
}
/*
* Delay before trying again.
*/
if (nsec <= MAXSLEEP/2)
sleep(nsec);
}
return(-1);
}
unix 環境ブックの高度なプログラミングで参照されています。
以下も使用できます。
SO_REUSEADDR
でsetsockopt()
。これにより、ローカル アドレスの再利用が可能になります。
元のサーバーに接続したのと同じ方法で、新しいサーバーに接続します。このための別の API はありません。なぜ違うと思うのか理解できない..
何でも可能だということから始めましょう。あなたのためにそれを行う機能があります。connect
これは、 TCP クライアントに使用したものと同じです。この接続をいつ再度呼び出す必要があるかを考える必要があります。
connect
では、いつその機能を使用するのでしょうか?
考えられる解決策を 1 つ紹介します。
サーバープロセスの状態を追跡する何らかの監視ソフトウェア(おそらくデーモン)が必要です。たとえば、サーバー プロセスが生きているかどうかを定期的に調べます。
単一のクライアントとサーバーの場合を考えてみましょう。クライアントはシステム A で実行されています。システム B 上のサーバー。
recv
サーバーが実行され、何かを編集する直前にクラッシュしたとします。これは、クライアントがサーバーに正常に接続され、send
失敗することを意味します。がsend
失敗した場合は、システム B の監視ソフトウェアに連絡して、何が起こったかを確認できます。
監視ソフトウェアがサーバーに問題が見つからなかったと報告した場合は、何か他の問題が発生しています (おそらく割り込み、NIC の故障など)。これらの理由は、この説明の範囲外です。
監視ソフトウェアが、サーバー プログラムが停止したことを検出したと応答した場合は、次のことができます。
- サーバーの再起動を求める監視ソフトウェアに応答する
- または、シャットダウンするように指示する
- または、あなたが適切だと思う他のことをしてください。
ここで、システム A のクライアントでsocket
、connect
、send
、recv
、 などのプロセスを再び開始します。
基本的に、現在のサーバー Y を監視する別のサーバー X を作成します。サーバー Y が停止すると、サーバー X に理由を求めます。