mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-15 00:15:15 +08:00
123 lines
3.9 KiB
C#
123 lines
3.9 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Net.Security;
|
|
using System.Net.Sockets;
|
|
using System.Security.Authentication;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Threading.Tasks;
|
|
using MQTTnet.Core.Channel;
|
|
using MQTTnet.Core.Client;
|
|
using MQTTnet.Core.Exceptions;
|
|
|
|
namespace MQTTnet
|
|
{
|
|
/// <summary>
|
|
/// Describes an SSL channel to a client.
|
|
/// </summary>
|
|
public class MqttServerSslChannel : IMqttCommunicationChannel, IDisposable
|
|
{
|
|
private readonly Socket _socket;
|
|
private readonly SslStream _sslStream;
|
|
private readonly X509Certificate2 _cert;
|
|
|
|
/// <summary>
|
|
/// Creates a new <see cref="MqttClientSslChannel"/> with a predefined <paramref name="socket"/>.
|
|
/// </summary>
|
|
/// <param name="socket">The client socket.</param>
|
|
/// <param name="cert">The X509 certificate used to authenticate as a server.</param>
|
|
public MqttServerSslChannel(Socket socket, X509Certificate2 cert)
|
|
{
|
|
_socket = socket ?? throw new ArgumentNullException(nameof(socket));
|
|
_cert = cert ?? throw new ArgumentNullException(nameof(cert));
|
|
|
|
if (!_socket.Connected)
|
|
return;
|
|
|
|
NetworkStream ns = new NetworkStream(_socket, true);
|
|
_sslStream = new SslStream(ns);
|
|
}
|
|
|
|
public Task Authenticate()
|
|
{
|
|
return _sslStream.AuthenticateAsServerAsync(_cert, false, SslProtocols.Tls12, false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously connects to the client described in the <see cref="MqttClientOptions"/>.
|
|
/// </summary>
|
|
/// <param name="options">The <see cref="MqttClientOptions"/> describing the connection.</param>
|
|
public Task ConnectAsync(MqttClientOptions options)
|
|
{
|
|
try
|
|
{
|
|
return _socket.ConnectAsync(options.Server, options.Port);
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
throw new MqttCommunicationException(exception);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously disconnects the client from the server.
|
|
/// </summary>
|
|
public Task DisconnectAsync()
|
|
{
|
|
try
|
|
{
|
|
_socket.Dispose();
|
|
return Task.FromResult(0);
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
throw new MqttCommunicationException(exception);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously writes a sequence of bytes to the socket.
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer to write data from.</param>
|
|
public Task WriteAsync(byte[] buffer)
|
|
{
|
|
if (buffer == null)
|
|
throw new ArgumentNullException(nameof(buffer));
|
|
|
|
try
|
|
{
|
|
return _sslStream.WriteAsync(buffer, 0, buffer.Length);
|
|
}
|
|
catch (Exception ex)
|
|
when (ex is SocketException || ex is IOException)
|
|
{
|
|
throw new MqttCommunicationException(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously reads a sequence of bytes from the socket.
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer to write the data into.</param>
|
|
public Task ReadAsync(byte[] buffer)
|
|
{
|
|
try
|
|
{
|
|
return _sslStream.ReadAsync(buffer, 0, buffer.Length);
|
|
}
|
|
catch (Exception ex)
|
|
when (ex is SocketException || ex is IOException)
|
|
{
|
|
throw new MqttCommunicationException(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases all resources used by the <see cref="MqttClientSslChannel"/>.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
_sslStream?.Dispose();
|
|
_socket?.Dispose();
|
|
}
|
|
}
|
|
} |