NetObserver.Helper 2.0.0

dotnet add package NetObserver.Helper --version 2.0.0
                    
NuGet\Install-Package NetObserver.Helper -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NetObserver.Helper" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NetObserver.Helper" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="NetObserver.Helper" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NetObserver.Helper --version 2.0.0
                    
#r "nuget: NetObserver.Helper, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NetObserver.Helper@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NetObserver.Helper&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=NetObserver.Helper&version=2.0.0
                    
Install as a Cake Tool

Changelog

All notable changes to NetObserver are documented in this file. For the Russian version, see CHANGELOG.ru.md.

[2.0.0] — Bug fixes, retarget to .NET Standard 2.1, and internal cleanup

This release addresses a set of real bugs found in the original 1.1.3 codebase (netstandard2.0), reduces duplicated code, and moves the target framework forward. The public API surface is backward compatible: existing consumers calling LocalIp, DnsInfo, IcmpRequestSender(Async), PingClassic(Async), Traceroute(Async), and the synchronous OpenPort.GetOpenPort(...) overloads should not need to change any call sites. New async overloads were added additively.

Fixed

  • LocalIp accumulated stale results across calls. The class used private static List<...> fields that were never cleared. Calling GetIpv4Localhost() or GetAllIpv4NetInterface() more than once could return addresses left over from a previous call (and was not thread-safe). Rewritten to build a fresh, local list on every call — nothing is cached or shared between calls anymore.
  • OpenPort could leak a pending connection attempt on timeout. The original code used the legacy BeginConnect/EndConnect pattern and called Socket.Close() on timeout without ever calling EndConnect, so a connection completing after the timeout could throw in the background after the socket was already disposed. Rewritten around TcpClient.ConnectAsync + Task.WhenAny, with the (possibly still pending) connect task's eventual exception explicitly observed, so it never surfaces as an unobserved task exception.
  • Lost stack traces when translating exceptions. Every ping/DNS/traceroute method re-threw caught exceptions using new SomeException(message, ex.InnerException) — passing the inner exception (frequently null) instead of the exception that was actually caught (ex). The original stack trace was discarded. Centralized into Common/ExceptionHelper, which always chains the true original exception, so Exception.InnerException / .ToString() now show the real failure point.
  • Misused ArgumentNullException/ArgumentOutOfRangeException constructors in a few call sites (passing a human-readable message where the API expects a parameter name, or vice-versa) — fixed via the same helper.
  • Hardcoded, machine-local absolute path in NetObserver.csproj (..\..\..\..\Users\Laise\Downloads\IconsPacket.png) pointed at the original author's local Downloads folder. Anyone else cloning the repository would fail to build the NuGet package (or silently lose the package icon). Fixed to reference Resources\IconsPacket.png, which already ships in the repository.

Changed

  • Target framework: netstandard2.0netstandard2.1.
  • EnableNETAnalyzers turned back on (it was explicitly disabled in the original project, which likely hid some of the issues above from the IDE/build).
  • LocalIp and DnsInfo are now static class (they only ever exposed static members; this prevents meaningless instantiation). Minor breaking change if any consumer did new LocalIp() / new DnsInfo() — unlikely, since none of their members were instance members.
  • Traceroute / TracerouteAsync: the _buffer field is now static readonly instead of a mutable instance field; the max-TTL default (previously inconsistently 31 in Traceroute vs. 30 in TracerouteAsync) is now 30 in both.
  • Reduced duplication:
    • IcmpRequestSender / IcmpRequestSenderAsync: the five nearly-identical catch blocks per overload were replaced by a single call into Common/ExceptionHelper.
    • Traceroute / TracerouteAsync: the four public overloads now delegate to two private core methods (TraceRouteCore(Async) / DetailTraceRouteCore(Async)) instead of duplicating the hop-walking loop.
    • LocalIp: four nearly-identical private methods collapsed into one, parameterized by PrefixOrigin.

Added

  • OpenPort.GetOpenPortAsync(...) — async, cancellable single-port and port-range scanning, with a maxConcurrency parameter (default 200) that bounds how many ports are probed in parallel, instead of the original's fully sequential range scan (which could block for minutes on wide ranges).
  • XML doc comments clarified/expanded, including an explicit note on GetDetailTraceRoute(Async) explaining why it sends a second, direct ping per hop (to get a normal PingReply — round-trip time, buffer, and a Success status — instead of exposing the raw TtlExpired reply). This was flagged in review as possibly redundant, but removing it would have changed observable behavior (and broken the existing GetDetailTraceRouteTest, which asserts Status == Success on every hop), so it was kept and documented instead of "fixed".

Compatibility note

netstandard2.1 is not supported by classic .NET Framework (4.x) — only .NET Core 3.0+, .NET 5+, and recent Mono/Xamarin. If your consumers are still on .NET Framework, this release (and 3.0.0) are not suitable; stay on 1.1.x or ask for a netstandard2.0 + netstandard2.1/net10.0 multi-target build.


[1.1.3] and earlier

Original releases by the upstream author, targeting netstandard2.0. See the project's GitHub history for details predating this fork/rewrite.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.1

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

* Retarget to .NET Standard 2.1.
* Fix LocalIp accumulating stale results across calls (removed shared static state).
* Fix OpenPort leaking pending connection attempts on timeout; added async, cancellable, concurrency-limited port scanning.
* Preserve original stack traces when translating low-level exceptions.
* Removed a machine-local absolute path from the package icon reference.