При кодировании клиента/сервера Socket я решил реализовать HeartBeat, чтобы узнать, жив ли клиент, но затем искал другие способы сделать это и заметил этот фрагмент кода, который, похоже, делает именно это из описания:Как работает расширение Socket Keep-Alive? 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 требуется только в том случае, если у вас есть приемный разъем *" - это неверно. Существуют и другие причины использования Keepalive, такие как поддержание соединения в режиме ожидания, пока он долгое время простаивает (подумайте о подключении FTP-команды, которое не работает во время длительной передачи по соединению данных). Некоторые маршрутизаторы/межсетевые экраны закрывают незанятые соединения через некоторое время, поэтому Keepalive можно использовать для решения этой проблемы. –
@RemyLebeau: Вы правы, спасибо, что подняли его. Я отредактировал свой ответ для полноты –