SocketUtils.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /* Copyright (C) 2012-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Net;
  10. using System.Net.Sockets;
  11. using System.Text;
  12. namespace Utilities
  13. {
  14. public class SocketUtils
  15. {
  16. public static void SetKeepAlive(Socket socket, TimeSpan timeout)
  17. {
  18. // 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.
  19. SetKeepAlive(socket, true, timeout, TimeSpan.FromSeconds(1));
  20. }
  21. /// <param name="timeout">the timeout, in milliseconds, with no activity until the first keep-alive packet is sent</param>
  22. /// <param name="interval">the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received</param>
  23. public static void SetKeepAlive(Socket socket, bool enable, TimeSpan timeout, TimeSpan interval)
  24. {
  25. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
  26. // https://msdn.microsoft.com/en-us/library/dd877220.aspx
  27. byte[] tcp_keepalive = new byte[12];
  28. LittleEndianWriter.WriteUInt32(tcp_keepalive, 0, Convert.ToUInt32(enable));
  29. LittleEndianWriter.WriteUInt32(tcp_keepalive, 4, (uint)timeout.TotalMilliseconds);
  30. LittleEndianWriter.WriteUInt32(tcp_keepalive, 8, (uint)interval.TotalMilliseconds);
  31. socket.IOControl(IOControlCode.KeepAliveValues, tcp_keepalive, null);
  32. }
  33. /// <summary>
  34. /// Socket will be forcefully closed, all pending data will be ignored, and socket will be deallocated.
  35. /// </summary>
  36. public static void ReleaseSocket(Socket socket)
  37. {
  38. if (socket != null)
  39. {
  40. if (socket.Connected)
  41. {
  42. try
  43. {
  44. socket.Shutdown(SocketShutdown.Both);
  45. socket.Disconnect(false);
  46. }
  47. catch (ObjectDisposedException)
  48. {
  49. return;
  50. }
  51. catch (SocketException)
  52. { }
  53. }
  54. socket.Close();
  55. socket = null;
  56. GC.Collect();
  57. GC.WaitForPendingFinalizers();
  58. }
  59. }
  60. }
  61. }