diff --git a/Client/Client.csproj b/Client/Client.csproj index 14d5f1d1..b538096b 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -63,6 +63,7 @@ + diff --git a/Client/Core/Client.cs b/Client/Core/Client.cs index 30174d40..9ca8122b 100644 --- a/Client/Core/Client.cs +++ b/Client/Core/Client.cs @@ -70,6 +70,9 @@ namespace xClient.Core Payload } + public const uint KEEP_ALIVE_TIME = 5000; + public const uint KEEP_ALIVE_INTERVAL = 5000; + public const int HEADER_SIZE = 4; public const int MAX_PACKET_SIZE = (1024 * 1024) * 1; //1MB private Socket _handle; @@ -102,7 +105,8 @@ namespace xClient.Core Initialize(); _handle = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - _handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); + //_handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); + Misc.KeepAliveEx.SetKeepAliveEx(_handle, KEEP_ALIVE_INTERVAL, KEEP_ALIVE_TIME); _handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true); _handle.NoDelay = true; diff --git a/Client/Core/Misc/KeepAlive.cs b/Client/Core/Misc/KeepAlive.cs new file mode 100644 index 00000000..d71bc40d --- /dev/null +++ b/Client/Core/Misc/KeepAlive.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +namespace xClient.Core.Misc +{ + /// + /// Socket Extension for KeepAlive + /// + /// Abdullah Saleem + /// a.saleem2993@gmail.com + public static class KeepAliveEx + { + /// + /// Sets the Keep-Alive values for the current tcp connection + /// + /// Current socket instance + /// 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. + /// 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. + public static void SetKeepAliveEx( /*this */ Socket socket, uint keepAliveInterval, uint keepAliveTime) + //extension removed, Missing System.Core.dll + { + 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); + } + + /// + /// Sets the Keep-Alive values for the current tcp connection + /// + /// Current socket instance + /// 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. + /// 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. + public static void SetKeepAlive(Socket socket, uint keepAliveInterval, uint keepAliveTime) + { + // //Removed, LINQ + // //byte[] dataWord = + // // (new byte[] { 0x01, 0x00, 0x00, 0x00 }).Concat(BitConverter.GetBytes(keepAliveTime)) + // // .Concat(BitConverter.GetBytes(keepAliveInterval)) + // // .ToArray(); + + byte[] dataWord; + using (var memoryStream = new MemoryStream()) + { + using (var binaryWriter = new BinaryWriter(memoryStream)) + { + binaryWriter.Write(new byte[] {0x01, 0x00, 0x00, 0x00}); + binaryWriter.Write(keepAliveTime); + binaryWriter.Write(keepAliveInterval); + } + dataWord = memoryStream.ToArray(); + } + socket.IOControl(IOControlCode.KeepAliveValues, dataWord, null); + } + + + /// + /// A structure used by SetKeepAliveEx(obsolete) Method + /// + [StructLayout(LayoutKind.Sequential)] + internal struct TcpKeepAlive + { + internal uint onoff; + internal uint keepalivetime; + internal uint keepaliveinterval; + }; + } +} \ No newline at end of file diff --git a/Server/Core/Client.cs b/Server/Core/Client.cs index eaff934c..55c0c03a 100644 --- a/Server/Core/Client.cs +++ b/Server/Core/Client.cs @@ -58,6 +58,9 @@ namespace xServer.Core Payload } + public const uint KEEP_ALIVE_TIME = 5000; + public const uint KEEP_ALIVE_INTERVAL = 5000; + public const int HEADER_SIZE = 4; public const int MAX_PACKET_SIZE = (1024 * 1024) * 1; //1MB private Socket _handle; @@ -94,7 +97,10 @@ namespace xServer.Core _handle = sock; - _handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); + //_handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); + + Misc.KeepAliveEx.SetKeepAliveEx(_handle,KEEP_ALIVE_INTERVAL,KEEP_ALIVE_TIME); + _handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true); _handle.NoDelay = true; diff --git a/Server/Core/Misc/KeepAlive.cs b/Server/Core/Misc/KeepAlive.cs new file mode 100644 index 00000000..4bebcbfb --- /dev/null +++ b/Server/Core/Misc/KeepAlive.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +namespace xServer.Core.Misc +{ + /// + /// Socket Extension for KeepAlive + /// + /// Abdullah Saleem + /// a.saleem2993@gmail.com + public static class KeepAliveEx + { + /// + /// Sets the Keep-Alive values for the current tcp connection + /// + /// Current socket instance + /// 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. + /// 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. + public static void SetKeepAliveEx( /*this */ Socket socket, uint keepAliveInterval, uint keepAliveTime) + //extension removed, Missing System.Core.dll + { + 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); + } + + /// + /// Sets the Keep-Alive values for the current tcp connection + /// + /// Current socket instance + /// 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. + /// 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. + public static void SetKeepAlive(Socket socket, uint keepAliveInterval, uint keepAliveTime) + { + // //Removed, LINQ + // //byte[] dataWord = + // // (new byte[] { 0x01, 0x00, 0x00, 0x00 }).Concat(BitConverter.GetBytes(keepAliveTime)) + // // .Concat(BitConverter.GetBytes(keepAliveInterval)) + // // .ToArray(); + + byte[] dataWord; + using (var memoryStream = new MemoryStream()) + { + using (var binaryWriter = new BinaryWriter(memoryStream)) + { + binaryWriter.Write(new byte[] { 0x01, 0x00, 0x00, 0x00 }); + binaryWriter.Write(keepAliveTime); + binaryWriter.Write(keepAliveInterval); + } + dataWord = memoryStream.ToArray(); + } + socket.IOControl(IOControlCode.KeepAliveValues, dataWord, null); + } + + + /// + /// A structure used by SetKeepAliveEx(obsolete) Method + /// + [StructLayout(LayoutKind.Sequential)] + internal struct TcpKeepAlive + { + internal uint onoff; + internal uint keepalivetime; + internal uint keepaliveinterval; + }; + } +} diff --git a/Server/Server.csproj b/Server/Server.csproj index 16e0e41e..92d8a106 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -384,6 +384,7 @@ Resources.resx True + SettingsSingleFileGenerator Settings.Designer.cs