diff --git a/Directory.Build.props b/Directory.Build.props index 97106bc..35d79fe 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -43,10 +43,10 @@ - + - + \ No newline at end of file diff --git a/sample/Atc.Network.Console.Tcp/Atc.Network.Console.Tcp.csproj b/sample/Atc.Network.Console.Tcp/Atc.Network.Console.Tcp.csproj index 0eb6055..7c70b6e 100644 --- a/sample/Atc.Network.Console.Tcp/Atc.Network.Console.Tcp.csproj +++ b/sample/Atc.Network.Console.Tcp/Atc.Network.Console.Tcp.csproj @@ -8,7 +8,7 @@ - + diff --git a/sample/Atc.Network.Console.Udp/Atc.Network.Console.Udp.csproj b/sample/Atc.Network.Console.Udp/Atc.Network.Console.Udp.csproj index 6176419..5a9ec72 100644 --- a/sample/Atc.Network.Console.Udp/Atc.Network.Console.Udp.csproj +++ b/sample/Atc.Network.Console.Udp/Atc.Network.Console.Udp.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Atc.Network/Atc.Network.csproj b/src/Atc.Network/Atc.Network.csproj index 726498f..66a828a 100644 --- a/src/Atc.Network/Atc.Network.csproj +++ b/src/Atc.Network/Atc.Network.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Atc.Network/LoggingEventIdConstants.cs b/src/Atc.Network/LoggingEventIdConstants.cs index 996d4f2..32d7ee1 100644 --- a/src/Atc.Network/LoggingEventIdConstants.cs +++ b/src/Atc.Network/LoggingEventIdConstants.cs @@ -16,10 +16,12 @@ internal static class TcpClient public const int Disconnected = 10009; public const int DataSendingByteLength = 10010; - public const int DataReceivedByteLength = 10011; - public const int DataReceiveTimeout = 10012; - public const int DataReceiveNoData = 10013; - public const int DataReceiveError = 10014; + public const int DataSendingSocketError = 10011; + public const int DataSendingError = 10012; + public const int DataReceivedByteLength = 10013; + public const int DataReceiveTimeout = 10014; + public const int DataReceiveNoData = 10015; + public const int DataReceiveError = 10016; } internal static class TcpServer @@ -41,11 +43,15 @@ internal static class UdpClient public const int ClientNotConnected = 10207; public const int Disconnecting = 10208; public const int Disconnected = 10209; + public const int DataSendingSocketError = 10210; + public const int DataSendingError = 10211; } internal static class UdpServer { public const int DataReceivedByteLength = 10311; public const int NotRunning = 10320; + public const int DataSendingSocketError = 10321; + public const int DataSendingError = 10322; } } \ No newline at end of file diff --git a/src/Atc.Network/Tcp/TcpClient.cs b/src/Atc.Network/Tcp/TcpClient.cs index 80e5727..9ecc829 100644 --- a/src/Atc.Network/Tcp/TcpClient.cs +++ b/src/Atc.Network/Tcp/TcpClient.cs @@ -280,8 +280,33 @@ public async Task Send( LogDataSendingByteLength(data.Length); - await networkStream!.WriteAsync(data.AsMemory(0, data.Length), cancellationToken); - await networkStream.FlushAsync(cancellationToken); + await SyncLock.WaitAsync(cancellationToken); + var disconnectedDueToException = false; + + try + { + await networkStream!.WriteAsync(data.AsMemory(0, data.Length), cancellationToken); + await networkStream.FlushAsync(cancellationToken); + } + catch (SocketException ex) + { + LogDataSendingSocketError(ex.SocketErrorCode.ToString(), ex.Message); + disconnectedDueToException = true; + } + catch (Exception ex) + { + LogDataSendingError(ex.Message); + disconnectedDueToException = true; + } + finally + { + SyncLock.Release(); + } + + if (disconnectedDueToException) + { + await DoDisconnect(raiseEventsAndLog: true, dispose: true); + } } /// @@ -497,10 +522,10 @@ private async Task SetConnected( bool raiseEvents, CancellationToken cancellationToken = default) { + await SyncLock.WaitAsync(cancellationToken); + try { - await SyncLock.WaitAsync(cancellationToken); - if (IsConnected) { return; @@ -523,10 +548,10 @@ private async Task SetDisconnected( bool dispose, CancellationToken cancellationToken = default) { + await SyncLock.WaitAsync(cancellationToken); + try { - await SyncLock.WaitAsync(cancellationToken); - if (!IsConnected) { return; diff --git a/src/Atc.Network/Tcp/TcpClientLoggerMessages.cs b/src/Atc.Network/Tcp/TcpClientLoggerMessages.cs index 381e9e2..5d7d13d 100644 --- a/src/Atc.Network/Tcp/TcpClientLoggerMessages.cs +++ b/src/Atc.Network/Tcp/TcpClientLoggerMessages.cs @@ -99,6 +99,21 @@ private partial void LogDisconnected( private partial void LogDataSendingByteLength( int byteLength); + [LoggerMessage( + EventId = LoggingEventIdConstants.TcpClient.DataSendingSocketError, + Level = LogLevel.Error, + Message = "Received error when sending data - {socketError}: {errorMessage}.")] + private partial void LogDataSendingSocketError( + string socketError, + string errorMessage); + + [LoggerMessage( + EventId = LoggingEventIdConstants.TcpClient.DataSendingError, + Level = LogLevel.Error, + Message = "Received error when sending data: {errorMessage}.")] + private partial void LogDataSendingError( + string errorMessage); + [LoggerMessage( EventId = LoggingEventIdConstants.TcpClient.DataReceivedByteLength, Level = LogLevel.Trace, diff --git a/src/Atc.Network/Udp/UdpClient.cs b/src/Atc.Network/Udp/UdpClient.cs index ace4fdf..e2b927b 100644 --- a/src/Atc.Network/Udp/UdpClient.cs +++ b/src/Atc.Network/Udp/UdpClient.cs @@ -181,8 +181,33 @@ public async Task Send( TerminationHelper.AppendTerminationBytesIfNeeded(ref data, terminationType); var buffer = new ArraySegment(data); - await socket!.SendToAsync(buffer, SocketFlags.None, RemoteEndPoint, cancellationToken); - await Task.Delay(TimeSpan.FromMilliseconds(1), cancellationToken); + await SyncLock.WaitAsync(cancellationToken); + var disconnectedDueToException = false; + + try + { + await socket!.SendToAsync(buffer, SocketFlags.None, RemoteEndPoint, cancellationToken); + await Task.Delay(TimeSpan.FromMilliseconds(1), cancellationToken); + } + catch (SocketException ex) + { + LogDataSendingSocketError(ex.SocketErrorCode.ToString(), ex.Message); + disconnectedDueToException = true; + } + catch (Exception ex) + { + LogDataSendingError(ex.Message); + disconnectedDueToException = true; + } + finally + { + SyncLock.Release(); + } + + if (disconnectedDueToException) + { + await DoDisconnect(raiseEventsAndLog: true); + } } /// @@ -351,10 +376,10 @@ private async Task SetConnected( bool raiseEvents, CancellationToken cancellationToken = default) { + await SyncLock.WaitAsync(cancellationToken); + try { - await SyncLock.WaitAsync(cancellationToken); - if (IsConnected) { return; @@ -376,10 +401,10 @@ private async Task SetDisconnected( bool raiseEvents = true, CancellationToken cancellationToken = default) { + await SyncLock.WaitAsync(cancellationToken); + try { - await SyncLock.WaitAsync(cancellationToken); - if (!IsConnected) { return; diff --git a/src/Atc.Network/Udp/UdpClientLoggerMessages.cs b/src/Atc.Network/Udp/UdpClientLoggerMessages.cs index c28e46a..d6d5246 100644 --- a/src/Atc.Network/Udp/UdpClientLoggerMessages.cs +++ b/src/Atc.Network/Udp/UdpClientLoggerMessages.cs @@ -57,4 +57,19 @@ private partial void LogDisconnecting( private partial void LogDisconnected( string ipAddressOrHostName, int port); + + [LoggerMessage( + EventId = LoggingEventIdConstants.UdpClient.DataSendingSocketError, + Level = LogLevel.Error, + Message = "Received error when sending data - {socketError}: {errorMessage}.")] + private partial void LogDataSendingSocketError( + string socketError, + string errorMessage); + + [LoggerMessage( + EventId = LoggingEventIdConstants.UdpClient.DataSendingError, + Level = LogLevel.Error, + Message = "Received error when sending data: {errorMessage}.")] + private partial void LogDataSendingError( + string errorMessage); } \ No newline at end of file diff --git a/src/Atc.Network/Udp/UdpServer.cs b/src/Atc.Network/Udp/UdpServer.cs index ad113ad..6ca934a 100644 --- a/src/Atc.Network/Udp/UdpServer.cs +++ b/src/Atc.Network/Udp/UdpServer.cs @@ -204,7 +204,19 @@ public async Task Send( AppendTerminationBytesIfNeeded(ref data, terminationType); var buffer = new ArraySegment(data); - await socket!.SendToAsync(buffer, SocketFlags.None, recipient, cancellationToken); + + try + { + await socket!.SendToAsync(buffer, SocketFlags.None, recipient, cancellationToken); + } + catch (SocketException ex) + { + LogDataSendingSocketError(ex.SocketErrorCode.ToString(), ex.Message); + } + catch (Exception ex) + { + LogDataSendingError(ex.Message); + } } /// diff --git a/src/Atc.Network/Udp/UdpServerLoggerMessages.cs b/src/Atc.Network/Udp/UdpServerLoggerMessages.cs index dee88d8..8130c8f 100644 --- a/src/Atc.Network/Udp/UdpServerLoggerMessages.cs +++ b/src/Atc.Network/Udp/UdpServerLoggerMessages.cs @@ -21,4 +21,19 @@ public partial class UdpServer Message = "Received '{byteLength}' bytes.")] private partial void LogDataReceived( int byteLength); + + [LoggerMessage( + EventId = LoggingEventIdConstants.UdpServer.DataSendingSocketError, + Level = LogLevel.Error, + Message = "Received error when sending data - {socketError}: {errorMessage}.")] + private partial void LogDataSendingSocketError( + string socketError, + string errorMessage); + + [LoggerMessage( + EventId = LoggingEventIdConstants.UdpServer.DataSendingError, + Level = LogLevel.Error, + Message = "Received error when sending data: {errorMessage}.")] + private partial void LogDataSendingError( + string errorMessage); } \ No newline at end of file diff --git a/test/Atc.Network.Test/Atc.Network.Test.csproj b/test/Atc.Network.Test/Atc.Network.Test.csproj index 7a29ea0..e109ad0 100644 --- a/test/Atc.Network.Test/Atc.Network.Test.csproj +++ b/test/Atc.Network.Test/Atc.Network.Test.csproj @@ -9,11 +9,11 @@ - + - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all