Improved stability of Tcp/Udp Reading/Writing

master
Jonas Arnold 3 years ago
parent 0da1a83e7c
commit c6d20bcc6a
  1. 2
      MultiTerm.Protocols/CommunicationProtocol.cs
  2. 12
      MultiTerm.Protocols/Tcp/TcpClientProtocol.cs
  3. 24
      MultiTerm.Protocols/Udp/UdpProtocol.cs

@ -151,7 +151,7 @@ public abstract class CommunicationProtocol : ICommunicationProtocol
else
{
this.logger.LogWarn($"'{nameof(Connect)}()' failed to connect to protocol, did not start reading thread.", nameof(CommunicationProtocol));
this.messenger.Send<IUserInterfaceMessage>(new GenericUserInterfaceMessage("Failed to connect to protocol, for more information please check logfile.", MessageImportance.High));
this.messenger.Send<IUserInterfaceMessage>(new GenericUserInterfaceMessage($"Failed to connect to '{this.GetProtocolAndInstanceIdentifier()}'. For more information please check logfile.", MessageImportance.High));
return false;
}
}

@ -134,6 +134,18 @@ public class TcpClientProtocol : CommunicationProtocol
this.OnUnintentionallyDisconnected();
break; // break loop
}
catch (IOException ioEx)
{
// socket exception and timeout => normal use case
if (ioEx.InnerException is SocketException sockEx && sockEx?.SocketErrorCode == SocketError.TimedOut) { }
// other IO Exception
else
{
this.logger.LogException(ioEx, $"IOException while reading data in {nameof(InternalRead)}", nameof(TcpClientProtocol));
this.messenger.Send<IUserInterfaceMessage>(new StoppedReadingUIMessage(this, ioEx.ToString()));
break; // break loop
}
}
catch (Exception ex)
{
this.logger.LogException(ex, $"Exception while reading data in {nameof(InternalRead)}", nameof(TcpClientProtocol));

@ -5,6 +5,7 @@ using MultiTerm.Protocols.Helpers;
using MultiTerm.Protocols.Model;
using MultiTerm.Protocols.Network;
using MultiTerm.Protocols.Types;
using System.Net;
using System.Net.Sockets;
namespace MultiTerm.Protocols.Udp;
@ -19,6 +20,9 @@ public class UdpProtocol : CommunicationProtocol
private UdpClient? receivingUdpClient;
private UdpClient? sendingUdpClient;
private const int ReadTimeoutMs = 100; // milliseconds until the read operation timeouts
private const int WriteTimeoutMs = 100; // milliseconds until the write operation timeouts
public UdpProtocol(ILogger logger, IMessenger messenger) : base(logger, messenger) { }
protected override bool InternalConnect(IProtocolSettings settings)
@ -74,6 +78,10 @@ public class UdpProtocol : CommunicationProtocol
return false;
}
// set static settings
this.receivingUdpClient.Client.ReceiveTimeout = ReadTimeoutMs;
this.sendingUdpClient.Client.SendTimeout = WriteTimeoutMs;
return true;
}
@ -104,11 +112,12 @@ public class UdpProtocol : CommunicationProtocol
while (ct.IsCancellationRequested == false)
{
// try receive message
UdpReceiveResult receivedResult;
IPEndPoint? remoteEndPoint = null;
byte[] receivedBytes = Array.Empty<byte>();
try
{
// will throw ObjectDisposedException if null
receivedResult = this.receivingUdpClient!.ReceiveAsync(ct).GetAwaiter().GetResult();
receivedBytes = this.receivingUdpClient!.Receive(ref remoteEndPoint);
}
catch (OperationCanceledException) // intentionally cancelled => just break
{
@ -120,6 +129,16 @@ public class UdpProtocol : CommunicationProtocol
this.OnUnintentionallyDisconnected();
break; // break loop
}
catch (SocketException sockEx)
{
// timeout = normal use case
if (sockEx.SocketErrorCode != SocketError.TimedOut)
{
this.logger.LogException(sockEx, $"SocketException while reading data in {nameof(InternalRead)}", nameof(UdpProtocol));
this.messenger.Send<IUserInterfaceMessage>(new StoppedReadingUIMessage(this, sockEx.SocketErrorCode.ToString()));
break; // break loop
}
}
catch (Exception ex)
{
this.logger.LogException(ex, $"Exception while reading data in {nameof(InternalRead)}", nameof(UdpProtocol));
@ -128,7 +147,6 @@ public class UdpProtocol : CommunicationProtocol
}
// any data received?
byte[] receivedBytes = receivedResult.Buffer;
if (receivedBytes.Length > 0)
{
foreach (byte b in receivedBytes)

Loading…
Cancel
Save