Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

129 Zeilen
4.0 KiB

  1. using System;
  2. using System.Net.Security;
  3. using System.Net.Sockets;
  4. using System.Security.Authentication;
  5. using System.Security.Cryptography.X509Certificates;
  6. using System.Threading.Tasks;
  7. using MQTTnet.Core.Channel;
  8. using MQTTnet.Core.Client;
  9. using MQTTnet.Core.Exceptions;
  10. namespace MQTTnet.Implementations
  11. {
  12. public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable
  13. {
  14. private readonly Socket _socket;
  15. private SslStream _sslStream;
  16. public MqttTcpChannel()
  17. {
  18. _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
  19. }
  20. public MqttTcpChannel(Socket socket, SslStream sslStream)
  21. {
  22. _socket = socket ?? throw new ArgumentNullException(nameof(socket));
  23. _sslStream = sslStream;
  24. }
  25. public async Task ConnectAsync(MqttClientOptions options)
  26. {
  27. if (options == null) throw new ArgumentNullException(nameof(options));
  28. try
  29. {
  30. await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.GetPort(), null);
  31. if (options.TlsOptions.UseTls)
  32. {
  33. _sslStream = new SslStream(new NetworkStream(_socket, true));
  34. await _sslStream.AuthenticateAsClientAsync(options.Server, LoadCertificates(options), SslProtocols.Tls12, options.TlsOptions.CheckCertificateRevocation);
  35. }
  36. }
  37. catch (SocketException exception)
  38. {
  39. throw new MqttCommunicationException(exception);
  40. }
  41. }
  42. public Task DisconnectAsync()
  43. {
  44. try
  45. {
  46. _sslStream.Dispose();
  47. _socket.Dispose();
  48. return Task.FromResult(0);
  49. }
  50. catch (SocketException exception)
  51. {
  52. throw new MqttCommunicationException(exception);
  53. }
  54. }
  55. public Task WriteAsync(byte[] buffer)
  56. {
  57. if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  58. try
  59. {
  60. if (_sslStream != null)
  61. {
  62. return _sslStream.WriteAsync(buffer, 0, buffer.Length);
  63. }
  64. return Task.Factory.FromAsync(
  65. // ReSharper disable once AssignNullToNotNullAttribute
  66. _socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, null, null),
  67. _socket.EndSend);
  68. }
  69. catch (SocketException exception)
  70. {
  71. throw new MqttCommunicationException(exception);
  72. }
  73. }
  74. public Task ReadAsync(byte[] buffer)
  75. {
  76. if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  77. try
  78. {
  79. if (_sslStream != null)
  80. {
  81. return _sslStream.ReadAsync(buffer, 0, buffer.Length);
  82. }
  83. return Task.Factory.FromAsync(
  84. // ReSharper disable once AssignNullToNotNullAttribute
  85. _socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, null, null),
  86. _socket.EndReceive);
  87. }
  88. catch (SocketException exception)
  89. {
  90. throw new MqttCommunicationException(exception);
  91. }
  92. }
  93. public void Dispose()
  94. {
  95. _socket?.Dispose();
  96. _sslStream?.Dispose();
  97. }
  98. private static X509CertificateCollection LoadCertificates(MqttClientOptions options)
  99. {
  100. var certificates = new X509CertificateCollection();
  101. if (options.TlsOptions.Certificates == null)
  102. {
  103. return certificates;
  104. }
  105. foreach (var certificate in options.TlsOptions.Certificates)
  106. {
  107. certificates.Add(new X509Certificate(certificate));
  108. }
  109. return certificates;
  110. }
  111. }
  112. }