diff --git a/SMBLibrary/Server/SMBServer.cs b/SMBLibrary/Server/SMBServer.cs
index 525aa41..56b152b 100644
--- a/SMBLibrary/Server/SMBServer.cs
+++ b/SMBLibrary/Server/SMBServer.cs
@@ -112,6 +112,8 @@ namespace SMBLibrary.Server
return;
}
+ // Windows will set the TCP keepalive timeout to 120 seconds for an SMB connection
+ SocketUtils.SetKeepAlive(clientSocket, TimeSpan.FromMinutes(2));
ConnectionState state = new ConnectionState(Log);
// Disable the Nagle Algorithm for this tcp socket:
clientSocket.NoDelay = true;
diff --git a/SMBLibrary/Utilities/SocketUtils.cs b/SMBLibrary/Utilities/SocketUtils.cs
index 3231c21..60ab8b1 100644
--- a/SMBLibrary/Utilities/SocketUtils.cs
+++ b/SMBLibrary/Utilities/SocketUtils.cs
@@ -8,6 +8,25 @@ namespace Utilities
{
public class SocketUtils
{
+ public static void SetKeepAlive(Socket socket, TimeSpan timeout)
+ {
+ // The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second.
+ SetKeepAlive(socket, true, timeout, TimeSpan.FromSeconds(1));
+ }
+
+ /// the timeout, in milliseconds, with no activity until the first keep-alive packet is sent
+ /// the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received
+ public static void SetKeepAlive(Socket socket, bool enable, TimeSpan timeout, TimeSpan interval)
+ {
+ socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
+ // https://msdn.microsoft.com/en-us/library/dd877220.aspx
+ byte[] tcp_keepalive = new byte[12];
+ LittleEndianWriter.WriteUInt32(tcp_keepalive, 0, Convert.ToUInt32(enable));
+ LittleEndianWriter.WriteUInt32(tcp_keepalive, 4, (uint)timeout.TotalMilliseconds);
+ LittleEndianWriter.WriteUInt32(tcp_keepalive, 8, (uint)interval.TotalMilliseconds);
+ socket.IOControl(IOControlCode.KeepAliveValues, tcp_keepalive, null);
+ }
+
///
/// Socket will be forcefully closed, all pending data will be ignored, and socket will be deallocated.
///