From 2424e17172f6af82812ff9e63cb818167ccbc3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Gonz=C3=A1lez?= Date: Wed, 1 Apr 2026 14:19:31 +0200 Subject: [PATCH] Add extensions for Socket and TcpClient --- Lib/Network/SocketExtensions.cs | 71 ++++++++++++++++++++++++++++++ Lib/Network/TcpClientExtensions.cs | 69 +++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 Lib/Network/SocketExtensions.cs create mode 100644 Lib/Network/TcpClientExtensions.cs diff --git a/Lib/Network/SocketExtensions.cs b/Lib/Network/SocketExtensions.cs new file mode 100644 index 0000000..6064e38 --- /dev/null +++ b/Lib/Network/SocketExtensions.cs @@ -0,0 +1,71 @@ +/// @file +/// @copyright Copyright (c) 2026 SafeTwice S.L. All rights reserved. +/// @license See LICENSE.txt + +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Utilities.DotNet.Network +{ + /// + /// Utility class providing extension methods for the class. + /// + public static class SocketExtensions + { + //=========================================================================== + // PUBLIC METHODS + //=========================================================================== + + /// + /// Establishes a connection to a remote host. + /// + /// Socket used to establish connection. + /// The IPAddress of the remote host to connect to. + /// The port on the remote host to connect to. + /// The number of milliseconds to wait for connection to be established, + /// or to wait indefinitely. + /// An error occurred when accessing the socket. + /// The has been disposed. + /// A caller higher in the call stack does not have permission for the requested operation. + /// The has been placed in a listening state by calling . + public static void Connect( this Socket socket, IPAddress address, int port, int timeout ) + { + if( timeout == Timeout.Infinite ) + { + socket.Connect( address, port ); + } + else + { + Task connectTask; + + try + { + connectTask = socket.ConnectAsync( address, port ); + + if( !connectTask.Wait( timeout ) ) + { + socket.Close(); + throw new SocketException( (int) SocketError.TimedOut ); + } + } + catch( AggregateException ex ) + { + socket.Close(); + throw ex.InnerException ?? ex; + } + catch( Exception ) + { + socket.Close(); + throw; + } + + Debug.Assert( !connectTask.IsFaulted ); + Debug.Assert( socket.Connected ); + } + } + } +} diff --git a/Lib/Network/TcpClientExtensions.cs b/Lib/Network/TcpClientExtensions.cs new file mode 100644 index 0000000..0fecc80 --- /dev/null +++ b/Lib/Network/TcpClientExtensions.cs @@ -0,0 +1,69 @@ +/// @file +/// @copyright Copyright (c) 2026 SafeTwice S.L. All rights reserved. +/// @license See LICENSE.txt + +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Utilities.DotNet.Network +{ + /// + /// Utility class providing extension methods for the class. + /// + public static class TcpClientExtensions + { + //=========================================================================== + // PUBLIC METHODS + //=========================================================================== + + /// + /// Establishes a connection to a remote TCP host. + /// + /// TCP client used to establish connection. + /// The IPAddress of the remote host to connect to. + /// The port on the remote host to connect to. + /// The number of milliseconds to wait for connection to be established, + /// or to wait indefinitely. + /// An error occurred when accessing the socket. + /// The has been disposed. + public static void Connect( this TcpClient client, IPAddress address, int port, int timeout ) + { + if( timeout == Timeout.Infinite ) + { + client.Connect( address, port ); + } + else + { + Task connectTask; + + try + { + connectTask = client.ConnectAsync( address, port ); + + if( !connectTask.Wait( timeout ) ) + { + client.Close(); + throw new SocketException( (int) SocketError.TimedOut ); + } + } + catch( AggregateException ex ) + { + client.Close(); + throw ex.InnerException ?? ex; + } + catch( Exception ) + { + client.Close(); + throw; + } + + Debug.Assert( !connectTask.IsFaulted ); + Debug.Assert( client.Connected ); + } + } + } +}