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