@@ -33,7 +33,6 @@ namespace Lextm.SharpSnmpLib.Messaging
33
33
public sealed partial class Discoverer
34
34
{
35
35
private int _active ;
36
- private int _bufferSize ;
37
36
private int _requestId ;
38
37
private static readonly UserRegistry Empty = new ( ) ;
39
38
private readonly IList < Variable > _defaultVariables = new List < Variable > { new ( new ObjectIdentifier ( new uint [ ] { 1 , 3 , 6 , 1 , 2 , 1 , 1 , 1 , 0 } ) ) } ;
@@ -88,7 +87,7 @@ public void Discover(VersionCode version, IPEndPoint broadcastAddress, OctetStri
88
87
using var udp = new UdpClient ( addressFamily ) ;
89
88
if ( addressFamily == AddressFamily . InterNetworkV6 )
90
89
{
91
- udp . JoinMulticastGroup ( broadcastAddress . Address ) ;
90
+ udp . MulticastLoopback = false ;
92
91
}
93
92
else if ( addressFamily == AddressFamily . InterNetwork )
94
93
{
@@ -108,12 +107,12 @@ public void Discover(VersionCode version, IPEndPoint broadcastAddress, OctetStri
108
107
return ;
109
108
}
110
109
111
- _bufferSize = udp . Client . ReceiveBufferSize = Messenger . MaxMessageSize ;
110
+ udp . Client . ReceiveBufferSize = Messenger . MaxMessageSize ;
112
111
113
112
#if ASYNC
114
- Task . Factory . StartNew ( ( ) => AsyncBeginReceive ( udp . Client ) ) ;
113
+ Task . Factory . StartNew ( ( ) => AsyncBeginReceive ( udp ) ) ;
115
114
#else
116
- Task . Factory . StartNew ( ( ) => AsyncReceive ( udp . Client ) ) ;
115
+ Task . Factory . StartNew ( ( ) => AsyncReceive ( udp ) ) ;
117
116
#endif
118
117
119
118
Thread . Sleep ( interval ) ;
@@ -198,7 +197,7 @@ private void AsyncEndReceive(IAsyncResult iar)
198
197
}
199
198
#else
200
199
201
- private void AsyncReceive ( Socket socket )
200
+ private void AsyncReceive ( UdpClient client )
202
201
{
203
202
while ( true )
204
203
{
@@ -210,10 +209,9 @@ private void AsyncReceive(Socket socket)
210
209
211
210
try
212
211
{
213
- var buffer = new byte [ _bufferSize ] ;
214
- EndPoint remote = new IPEndPoint ( IPAddress . Any , 0 ) ;
215
- var count = socket . ReceiveFrom ( buffer , ref remote ) ;
216
- Task . Factory . StartNew ( ( ) => HandleMessage ( buffer , count , ( IPEndPoint ) remote ) ) ;
212
+ var remote = new IPEndPoint ( IPAddress . Any , 0 ) ;
213
+ var buffer = client . Receive ( ref remote ) ;
214
+ Task . Factory . StartNew ( ( ) => HandleMessage ( buffer , buffer . Length , remote ) ) ;
217
215
}
218
216
catch ( SocketException ex )
219
217
{
@@ -298,11 +296,6 @@ public async Task DiscoverAsync(VersionCode version, IPEndPoint broadcastAddress
298
296
}
299
297
300
298
var addressFamily = broadcastAddress . AddressFamily ;
301
- if ( addressFamily == AddressFamily . InterNetworkV6 )
302
- {
303
- throw new ArgumentException ( "IP v6 is not yet supported." , nameof ( broadcastAddress ) ) ;
304
- }
305
-
306
299
byte [ ] bytes ;
307
300
_requestId = Messenger . NextRequestId ;
308
301
if ( version == VersionCode . V3 )
@@ -316,25 +309,32 @@ public async Task DiscoverAsync(VersionCode version, IPEndPoint broadcastAddress
316
309
bytes = message . ToBytes ( ) ;
317
310
}
318
311
319
- using var udp = new Socket ( addressFamily , SocketType . Dgram , ProtocolType . Udp ) ;
320
- udp . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . Broadcast , true ) ;
321
- var buffer = new ArraySegment < byte > ( bytes ) ;
322
- await udp . SendToAsync ( buffer , SocketFlags . None , broadcastAddress ) ;
312
+ using var udp = new UdpClient ( addressFamily ) ;
313
+ if ( addressFamily == AddressFamily . InterNetworkV6 )
314
+ {
315
+ udp . MulticastLoopback = false ;
316
+ }
317
+ else if ( addressFamily == AddressFamily . InterNetwork )
318
+ {
319
+ #if ( ! CF )
320
+ udp . EnableBroadcast = true ;
321
+ #endif
322
+ }
323
323
324
+ await udp . SendAsync ( bytes , bytes . Length , broadcastAddress ) ;
324
325
var activeBefore = Interlocked . CompareExchange ( ref _active , Active , Inactive ) ;
325
326
if ( activeBefore == Active )
326
327
{
327
328
// If already started, we've nothing to do.
328
329
return ;
329
330
}
330
331
331
- _bufferSize = udp . ReceiveBufferSize ;
332
332
#if NET6_0_OR_GREATER
333
333
var source = new CancellationTokenSource ( ) ;
334
334
source . CancelAfter ( interval ) ;
335
335
try
336
336
{
337
- await ReceiveAsync ( udp , source . Token ) ;
337
+ await ReceiveAsync ( udp . Client , source . Token ) ;
338
338
}
339
339
catch ( OperationCanceledException )
340
340
{
@@ -346,18 +346,10 @@ await Task.WhenAny(
346
346
Task . Delay ( interval ) ) ;
347
347
#endif
348
348
Interlocked . CompareExchange ( ref _active , Inactive , Active ) ;
349
- try
350
- {
351
- udp . Shutdown ( SocketShutdown . Both ) ;
352
- }
353
- catch ( SocketException )
354
- {
355
- // This exception is thrown in .NET Core <=2.1.4 on non-Windows systems.
356
- // However, the shutdown call is necessary to release the socket binding.
357
- }
349
+ udp . Close ( ) ;
358
350
}
359
351
#if ! NET6_0_OR_GREATER
360
- private async Task ReceiveAsync ( Socket socket )
352
+ private async Task ReceiveAsync ( UdpClient client )
361
353
{
362
354
while ( true )
363
355
{
@@ -369,11 +361,8 @@ private async Task ReceiveAsync(Socket socket)
369
361
370
362
try
371
363
{
372
- EndPoint remote = new IPEndPoint ( IPAddress . Any , 0 ) ;
373
-
374
- var buffer = new byte [ _bufferSize ] ;
375
- var result = await socket . ReceiveMessageFromAsync ( new ArraySegment < byte > ( buffer ) , SocketFlags . None , remote ) ;
376
- await Task . Factory . StartNew ( ( ) => HandleMessage ( buffer , result . ReceivedBytes , ( IPEndPoint ) result . RemoteEndPoint ) )
364
+ var result = await client . ReceiveAsync ( ) ;
365
+ await Task . Factory . StartNew ( ( ) => HandleMessage ( result . Buffer , result . Buffer . Length , result . RemoteEndPoint ) )
377
366
. ConfigureAwait ( false ) ;
378
367
}
379
368
catch ( SocketException ex )
0 commit comments