2014-04-10 15:06:54 +00:00
|
|
|
|
using MediaBrowser.Model.Logging;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
2014-04-25 17:30:41 +00:00
|
|
|
|
namespace MediaBrowser.Dlna.Ssdp
|
2014-04-10 15:06:54 +00:00
|
|
|
|
{
|
|
|
|
|
public class Datagram
|
|
|
|
|
{
|
2014-09-06 04:21:23 +00:00
|
|
|
|
public EndPoint ToEndPoint { get; private set; }
|
|
|
|
|
public EndPoint FromEndPoint { get; private set; }
|
2014-04-10 15:06:54 +00:00
|
|
|
|
public string Message { get; private set; }
|
2014-10-08 02:25:24 +00:00
|
|
|
|
public bool IgnoreBindFailure { get; private set; }
|
2015-05-04 17:44:25 +00:00
|
|
|
|
public bool EnableDebugLogging { get; private set; }
|
2014-04-25 17:30:41 +00:00
|
|
|
|
|
2014-04-10 15:06:54 +00:00
|
|
|
|
private readonly ILogger _logger;
|
|
|
|
|
|
2015-05-04 17:44:25 +00:00
|
|
|
|
public Datagram(EndPoint toEndPoint, EndPoint fromEndPoint, ILogger logger, string message, bool ignoreBindFailure, bool enableDebugLogging)
|
2014-04-10 15:06:54 +00:00
|
|
|
|
{
|
|
|
|
|
Message = message;
|
|
|
|
|
_logger = logger;
|
2015-05-04 17:44:25 +00:00
|
|
|
|
EnableDebugLogging = enableDebugLogging;
|
2014-10-08 02:25:24 +00:00
|
|
|
|
IgnoreBindFailure = ignoreBindFailure;
|
2014-05-01 03:24:55 +00:00
|
|
|
|
FromEndPoint = fromEndPoint;
|
|
|
|
|
ToEndPoint = toEndPoint;
|
2014-04-10 15:06:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Send()
|
|
|
|
|
{
|
|
|
|
|
var msg = Encoding.ASCII.GetBytes(Message);
|
2015-05-07 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
var socket = CreateSocket();
|
|
|
|
|
|
|
|
|
|
if (socket == null)
|
2014-04-10 15:06:54 +00:00
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2014-04-25 17:30:41 +00:00
|
|
|
|
|
2015-05-07 22:27:01 +00:00
|
|
|
|
if (FromEndPoint != null)
|
|
|
|
|
{
|
|
|
|
|
try
|
2014-05-01 03:24:55 +00:00
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
socket.Bind(FromEndPoint);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (EnableDebugLogging)
|
2014-10-08 02:25:24 +00:00
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
_logger.ErrorException("Error binding datagram socket", ex);
|
2014-10-08 02:25:24 +00:00
|
|
|
|
}
|
2015-05-07 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
if (!IgnoreBindFailure)
|
2014-10-08 02:25:24 +00:00
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
CloseSocket(socket, false);
|
|
|
|
|
|
|
|
|
|
return;
|
2014-10-08 02:25:24 +00:00
|
|
|
|
}
|
2014-05-01 03:24:55 +00:00
|
|
|
|
}
|
2015-05-07 22:27:01 +00:00
|
|
|
|
}
|
2014-04-25 17:30:41 +00:00
|
|
|
|
|
2015-05-07 22:27:01 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
socket.BeginSendTo(msg, 0, msg.Length, SocketFlags.None, ToEndPoint, result =>
|
2014-04-10 15:06:54 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
socket.EndSend(result);
|
2014-04-10 15:06:54 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2015-05-04 17:44:25 +00:00
|
|
|
|
if (!IgnoreBindFailure || EnableDebugLogging)
|
2014-10-08 02:25:24 +00:00
|
|
|
|
{
|
|
|
|
|
_logger.ErrorException("Error sending Datagram to {0} from {1}: " + Message, ex, ToEndPoint, FromEndPoint == null ? "" : FromEndPoint.ToString());
|
|
|
|
|
}
|
2014-04-10 15:06:54 +00:00
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
CloseSocket(socket, true);
|
2014-04-10 15:06:54 +00:00
|
|
|
|
}
|
|
|
|
|
}, null);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2014-08-26 02:30:52 +00:00
|
|
|
|
_logger.ErrorException("Error sending Datagram to {0} from {1}: " + Message, ex, ToEndPoint, FromEndPoint == null ? "" : FromEndPoint.ToString());
|
2015-05-07 22:27:01 +00:00
|
|
|
|
CloseSocket(socket, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CloseSocket(Socket socket, bool logError)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
socket.Close();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (logError && EnableDebugLogging)
|
|
|
|
|
{
|
|
|
|
|
_logger.ErrorException("Error closing datagram socket", ex);
|
|
|
|
|
}
|
2014-04-10 15:06:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-25 17:30:41 +00:00
|
|
|
|
|
|
|
|
|
private Socket CreateSocket()
|
|
|
|
|
{
|
2015-05-07 22:27:01 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
2014-04-25 17:30:41 +00:00
|
|
|
|
|
2015-05-07 22:27:01 +00:00
|
|
|
|
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
|
|
|
|
return socket;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.ErrorException("Error creating socket", ex);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2014-04-25 17:30:41 +00:00
|
|
|
|
}
|
2014-04-10 15:06:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|