diff --git a/MultiTerm.Protocols/CommunicationProtocol.cs b/MultiTerm.Protocols/CommunicationProtocol.cs index d056d81..5ac8a26 100644 --- a/MultiTerm.Protocols/CommunicationProtocol.cs +++ b/MultiTerm.Protocols/CommunicationProtocol.cs @@ -60,7 +60,7 @@ public abstract class CommunicationProtocol : ICommunicationProtocol /// /// To be called whenever the protocol detected that it is disconnected, but this is not a known fact. /// - protected void OnUnintentionallyDisconnected() + protected void OnUnintentionallyDisconnected(bool informUser = true) { // perform all steps in a task, to prevent deadlock when this method is called from a thread that is joined. Task.Run(() => @@ -72,7 +72,10 @@ public abstract class CommunicationProtocol : ICommunicationProtocol this.State = ProtocolConnectionState.UnintentionallyDisconnected; // inform user - this.messenger.Send(new GenericUserInterfaceMessage($"'{this.GetProtocolAndInstanceIdentifier()}' unintentionally disconnected.", MessageImportance.High)); + if (informUser) + { + this.messenger.Send(new GenericUserInterfaceMessage($"'{this.GetProtocolAndInstanceIdentifier()}' unintentionally disconnected.", MessageImportance.High)); + } }); } diff --git a/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs b/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs index f24b6b9..dd78da9 100644 --- a/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs +++ b/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs @@ -47,7 +47,8 @@ public class TcpClientProtocol : CommunicationProtocol // check if client is null if (this.client != null) { - throw new Exception($"The TCP client was not null when {nameof(InternalConnect)} was called."); + this.client = null; + this.logger.LogWarn($"The TCP client was not null when {nameof(InternalConnect)} was called.", nameof(TcpClientProtocol)); } /* create client */ @@ -73,7 +74,14 @@ public class TcpClientProtocol : CommunicationProtocol // send message to inform about resolved IP address if (this.client.Client.RemoteEndPoint is IPEndPoint remoteEndpoint) { - this.messenger.Send(new TcpConnectedMessage(remoteEndpoint.Address)); + IPAddress remoteEndpointAddress = remoteEndpoint.Address; + // special handling for IPv4MappedToIPv6 addresses + if (remoteEndpointAddress.IsIPv4MappedToIPv6) + { + remoteEndpointAddress = remoteEndpoint.Address.MapToIPv4(); + } + + this.messenger.Send(new TcpConnectedMessage(remoteEndpointAddress)); } return true; @@ -128,25 +136,30 @@ public class TcpClientProtocol : CommunicationProtocol catch (ObjectDisposedException objex) { this.logger.LogException(objex, $"ObjectDisposedException while sending data in {nameof(InternalRead)}", nameof(TcpClientProtocol)); - this.OnUnintentionallyDisconnected(); + this.OnUnintentionallyDisconnected(informUser: true); break; // break loop } - catch (IOException ioEx) + catch (IOException ioEx) when (ioEx.InnerException is SocketException sockEx) { - // socket exception and timeout => normal use case - if (ioEx.InnerException is SocketException sockEx && sockEx?.SocketErrorCode == SocketError.TimedOut) { } - // other IO Exception - else + // socket exception timeout => normal use case => do nothing + if (sockEx.SocketErrorCode != SocketError.TimedOut) { - this.logger.LogException(ioEx, $"IOException while reading data in {nameof(InternalRead)}", nameof(TcpClientProtocol)); - this.messenger.Send(new StoppedReadingUIMessage(this, ioEx.ToString())); + this.logger.LogException(sockEx, $"SocketException with SocketErrorCode={sockEx.SocketErrorCode} while reading data in {nameof(InternalRead)}", nameof(TcpClientProtocol)); + this.messenger.Send(new StoppedReadingUIMessage(this, $"Socket Error: {sockEx.SocketErrorCode}")); + this.OnUnintentionallyDisconnected(informUser: false); break; // break loop } } + catch (IOException ioEx) + { + this.logger.LogException(ioEx, $"IOException while reading data in {nameof(InternalRead)}", nameof(TcpClientProtocol)); + this.OnUnintentionallyDisconnected(informUser: true); + break; // break loop + } catch (Exception ex) { this.logger.LogException(ex, $"Exception while reading data in {nameof(InternalRead)}", nameof(TcpClientProtocol)); - this.messenger.Send(new StoppedReadingUIMessage(this, ex.Message)); + this.OnUnintentionallyDisconnected(informUser: true); break; // break loop } diff --git a/MultiTerm.Protocols/Udp/UdpProtocol.cs b/MultiTerm.Protocols/Udp/UdpProtocol.cs index bdf3260..6f6f65a 100644 --- a/MultiTerm.Protocols/Udp/UdpProtocol.cs +++ b/MultiTerm.Protocols/Udp/UdpProtocol.cs @@ -45,8 +45,9 @@ public class UdpProtocol : CommunicationProtocol // check if client is null if(this.udpClient != null) { - throw new Exception($"UDP client was not null when {nameof(InternalConnect)} was called: " + - $"{nameof(udpClient)} isnull={this.udpClient == null},"); + this.udpClient = null; + this.logger.LogWarn($"UDP client was not null when {nameof(InternalConnect)} was called: " + + $"{nameof(udpClient)} isnull={this.udpClient == null}", nameof(UdpProtocol)); } /* create udp client */ @@ -135,6 +136,12 @@ public class UdpProtocol : CommunicationProtocol // report received data this.OnReceivedData(new ExtendedByte(b)); } + + // after data was processed, send update with latest connected endpoint + if(remoteEndPoint != null) + { + this.messenger.Send(new UdpConnectedMessage(remoteEndPoint.Address)); + } } } } diff --git a/MultiTerm.Wpf/View/SettingsView/NetworkSettingsView.xaml b/MultiTerm.Wpf/View/SettingsView/NetworkSettingsView.xaml index 72eed13..0bc8342 100644 --- a/MultiTerm.Wpf/View/SettingsView/NetworkSettingsView.xaml +++ b/MultiTerm.Wpf/View/SettingsView/NetworkSettingsView.xaml @@ -50,21 +50,21 @@ - + - +