add udp error handling

This commit is contained in:
Luke Pulverenti
2016-11-04 19:57:21 -04:00
parent 67ad1db6b7
commit 25312d7d03
6 changed files with 85 additions and 95 deletions

View File

@@ -78,17 +78,6 @@ namespace Rssdp.Infrastructure
{
}
/// <summary>
/// Partial constructor.
/// </summary>
/// <param name="socketFactory">An implementation of the <see cref="ISocketFactory"/> interface that can be used to make new unicast and multicast sockets. Cannot be null.</param>
/// <param name="localPort">The specific local port to use for all sockets created by this instance. Specify zero to indicate the system should choose a free port itself.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception>
public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort)
: this(socketFactory, localPort, SsdpConstants.SsdpDefaultMulticastTimeToLive)
{
}
/// <summary>
/// Full constructor.
/// </summary>
@@ -170,7 +159,12 @@ namespace Rssdp.Infrastructure
EnsureSendSocketCreated();
// SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
await Repeat(SsdpConstants.UdpResendCount, TimeSpan.FromMilliseconds(100), () => SendMessageIfSocketNotDisposed(messageData, destination)).ConfigureAwait(false);
for (var i = 0; i < SsdpConstants.UdpResendCount; i++)
{
await SendMessageIfSocketNotDisposed(messageData, destination).ConfigureAwait(false);
await Task.Delay(100).ConfigureAwait(false);
}
}
/// <summary>
@@ -188,8 +182,17 @@ namespace Rssdp.Infrastructure
EnsureSendSocketCreated();
// SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
await Repeat(SsdpConstants.UdpResendCount, TimeSpan.FromMilliseconds(100),
() => SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo() { IpAddress = new IpAddressInfo { Address = SsdpConstants.MulticastLocalAdminAddress }, Port = SsdpConstants.MulticastPort })).ConfigureAwait(false);
for (var i = 0; i < SsdpConstants.UdpResendCount; i++)
{
await SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo
{
IpAddress = new IpAddressInfo { Address = SsdpConstants.MulticastLocalAdminAddress },
Port = SsdpConstants.MulticastPort
}).ConfigureAwait(false);
await Task.Delay(100).ConfigureAwait(false);
}
}
/// <summary>
@@ -255,28 +258,16 @@ namespace Rssdp.Infrastructure
#region Private Methods
private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination)
private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination)
{
var socket = _SendSocket;
if (socket != null)
{
await _SendSocket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
return _SendSocket.SendAsync(messageData, messageData.Length, destination);
}
else
{
ThrowIfDisposed();
}
}
private static async Task Repeat(int repetitions, TimeSpan delay, Func<Task> work)
{
for (int cnt = 0; cnt < repetitions; cnt++)
{
await work().ConfigureAwait(false);
if (delay != TimeSpan.Zero)
await Task.Delay(delay).ConfigureAwait(false);
}
ThrowIfDisposed();
return Task.FromResult(true);
}
private IUdpSocket ListenForBroadcastsAsync()