TcpClient.cs 4.0 KB

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