TcpClient.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #if NETFX_CORE && !UNITY_EDITOR && !ENABLE_IL2CPP
  2. using System;
  3. using Windows.Networking;
  4. using Windows.Networking.Sockets;
  5. namespace BestHTTP.PlatformSupport.TcpClient.WinRT
  6. {
  7. public sealed class TcpClient : IDisposable
  8. {
  9. #region Public Properties
  10. public bool Connected { get; private set; }
  11. public TimeSpan ConnectTimeout { get; set; }
  12. #endregion
  13. #region Private Properties
  14. internal StreamSocket Socket { get; set; }
  15. private System.IO.Stream Stream { get; set; }
  16. #endregion
  17. public TcpClient()
  18. {
  19. ConnectTimeout = TimeSpan.FromSeconds(2);
  20. }
  21. public void Connect(string hostName, int port)
  22. {
  23. //How to secure socket connections with TLS/SSL:
  24. //http://msdn.microsoft.com/en-us/library/windows/apps/jj150597.aspx
  25. //Networking in Windows 8 Apps - Using StreamSocket for TCP Communication
  26. //http://blogs.msdn.com/b/metulev/archive/2012/10/22/networking-in-windows-8-apps-using-streamsocket-for-tcp-communication.aspx
  27. Socket = new StreamSocket();
  28. Socket.Control.KeepAlive = true;
  29. Socket.Control.NoDelay = true;
  30. var host = new HostName(hostName);
  31. System.Threading.CancellationTokenSource tokenSource = new System.Threading.CancellationTokenSource();
  32. // https://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj710176.aspx#content
  33. try
  34. {
  35. if (ConnectTimeout > TimeSpan.Zero)
  36. tokenSource.CancelAfter(ConnectTimeout);
  37. var task = Socket.ConnectAsync(host, port.ToString(), SocketProtectionLevel.PlainSocket).AsTask(tokenSource.Token);
  38. task.ConfigureAwait(false);
  39. task.Wait();
  40. Connected = task.IsCompleted;
  41. }
  42. catch(AggregateException ex)
  43. {
  44. //https://msdn.microsoft.com/en-us/library/dd537614(v=vs.110).aspx?f=255&MSPPError=-2147217396
  45. Connected = false;
  46. if (ex.InnerException != null)
  47. //throw ex.InnerException;
  48. {
  49. if ( ex.Message.Contains("No such host is known") || ex.Message.Contains("unreachable host") )
  50. throw new Exception("Socket Exception: " + ex.Message);
  51. else
  52. throw ex.InnerException;
  53. }
  54. else
  55. throw ex;
  56. }
  57. finally {
  58. // https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource
  59. tokenSource.Dispose();
  60. }
  61. if (!Connected)
  62. throw new TimeoutException("Connection timed out!");
  63. }
  64. public bool IsConnected()
  65. {
  66. return true;
  67. }
  68. public System.IO.Stream GetStream()
  69. {
  70. if (Stream == null)
  71. Stream = new DataReaderWriterStream(this);
  72. return Stream;
  73. }
  74. public void Close()
  75. {
  76. Dispose();
  77. }
  78. #region IDisposeble
  79. private bool disposed = false;
  80. private void Dispose(bool disposing)
  81. {
  82. if (!disposed)
  83. {
  84. disposed = true;
  85. if (disposing)
  86. {
  87. if (Stream != null)
  88. Stream.Dispose();
  89. Stream = null;
  90. Connected = false;
  91. this.Socket.Dispose();
  92. }
  93. }
  94. }
  95. ~TcpClient()
  96. {
  97. Dispose(false);
  98. }
  99. public void Dispose()
  100. {
  101. Dispose(true);
  102. GC.SuppressFinalize(this);
  103. }
  104. #endregion
  105. }
  106. }
  107. #endif