ソケットクライアント/サーバーをコーディングするとき、私はHeartBeatを実装してクライアントが生存しているかどうかを確認しましたが、他の方法でコードを探し出し、説明と同じように見えます。ソケットキープアライブ拡張機能はどのように機能しますか? C#
public static class SocketExtensions
{
/// <summary>
/// A structure used by SetKeepAliveEx Method
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct TcpKeepAlive
{
internal uint onoff;
internal uint keepalivetime;
internal uint keepaliveinterval;
};
/// <summary>
/// Sets the Keep-Alive values for the current tcp connection
/// </summary>
/// <param name="socket">Current socket instance</param>
/// <param name="keepAliveInterval">Specifies how often TCP repeats keep-alive transmissions when no response is received. TCP sends keep-alive transmissions to verify that idle connections are still active. This prevents TCP from inadvertently disconnecting active lines.</param>
/// <param name="keepAliveTime">Specifies how often TCP sends keep-alive transmissions. TCP sends keep-alive transmissions to verify that an idle connection is still active. This entry is used when the remote system is responding to TCP. Otherwise, the interval between transmissions is determined by the value of the keepAliveInterval entry.</param>
public static void SetKeepAliveEx(this Socket socket, uint keepAliveInterval, uint keepAliveTime)
{
var keepAlive = new TcpKeepAlive
{
onoff = 1,
keepaliveinterval = keepAliveInterval,
keepalivetime = keepAliveTime
};
int size = Marshal.SizeOf(keepAlive);
IntPtr keepAlivePtr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(keepAlive, keepAlivePtr, true);
var buffer = new byte[size];
Marshal.Copy(keepAlivePtr, buffer, 0, size);
Marshal.FreeHGlobal(keepAlivePtr);
socket.IOControl(IOControlCode.KeepAliveValues, buffer, null);
}
}
HeartBeatを実装するよりはるかに簡単な方法で仕事をしているようですが、どうやって動作するのか分かりませんが、アンマネージドコードで何かをしているようです。もしそうなら、なぜですか?
説明ありがとう、ありがとう!
"*ただしKeepAliveは、受信専用ソケット*がある場合にのみ必要です。" - それは当てはまりません。キープアライブを使用する理由としては、長時間アイドル状態になっている間に接続を維持するなどの理由があります(データ接続で長時間の転送中にアイドル状態になっているFTPコマンド接続を考えてください)。ルータ/ファイアウォールの中には、しばらくしてアイドル状態の接続を閉じるものがあるため、Keepaliveを使用して対処することができます。 –
@RemyLebeau:あなたはそうです、持ち上げてくれてありがとう。私は完全性のために私の答えを編集しました –