Two leaks in NetworkReporter, the same family as the Bluetooth/APRS/radio
socket leaks fixed earlier:
1. ensureRotatorConnected/ensureFrequencyConnected assigned the field directly,
so a channel that opened but threw during the rest of setup was never
closed and remained referenced. Use a local `opened` and close it in the
catch, matching the pattern used in AprsIsClient/Ic705Controller/
Ft817Controller/BluetoothReporter.
2. write() only flipped connected=false on failure. The broken channel stayed
in the field, the next ensure* reconnected and overwrote it, and the old
channel was never closed. Now a failed write closes the channel and nulls
the field. The null check is identity-based (socket === field) so a stale
reference from a concurrent report can never close a newer channel.
State-machine probe: normal write keeps the socket, failed write closes and
nulls, next report reconnects fresh, and passing a stale reference does not
close the newer socket.