在编写Socket客户端/服务器时,我考虑实现HeartBeat来了解客户端是否存活,但后来寻找其他方法并发现这段代码似乎从描述中确实可以做到这一点:
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更简单地完成了任务,虽然我不太明白它是如何工作的,看起来似乎在处理非托管代码?如果是这样,为什么要这样做呢?
能否给出解释,谢谢!