diff options
| author | Luke <luke.pulverenti@gmail.com> | 2016-11-05 15:36:32 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-11-05 15:36:32 -0400 |
| commit | 36c01cfc7649b95c7ff63833424f1952e7889d07 (patch) | |
| tree | be560399d41766ff4ef6e49dd90c488e88838488 /Emby.Common.Implementations/Net | |
| parent | 398398f3018434de7c057dffccb6c0373ff97526 (diff) | |
| parent | a4832369bf3abe7afbc2a35faa991be1ace64494 (diff) | |
Merge pull request #2274 from MediaBrowser/dev
Dev
Diffstat (limited to 'Emby.Common.Implementations/Net')
| -rw-r--r-- | Emby.Common.Implementations/Net/SocketFactory.cs | 33 | ||||
| -rw-r--r-- | Emby.Common.Implementations/Net/UdpSocket.cs | 75 |
2 files changed, 55 insertions, 53 deletions
diff --git a/Emby.Common.Implementations/Net/SocketFactory.cs b/Emby.Common.Implementations/Net/SocketFactory.cs index 3a2cea12a..bb38c72da 100644 --- a/Emby.Common.Implementations/Net/SocketFactory.cs +++ b/Emby.Common.Implementations/Net/SocketFactory.cs @@ -37,22 +37,44 @@ namespace Emby.Common.Implementations.Net #region ISocketFactory Members /// <summary> + /// Creates a new UDP socket and binds it to the specified local port. + /// </summary> + /// <param name="localPort">An integer specifying the local port to bind the socket to.</param> + public IUdpSocket CreateUdpSocket(int localPort) + { + if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); + + var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + try + { + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + return new UdpSocket(retVal, localPort, _LocalIP); + } + catch + { + if (retVal != null) + retVal.Dispose(); + + throw; + } + } + + /// <summary> /// Creates a new UDP socket that is a member of the SSDP multicast local admin group and binds it to the specified local port. /// </summary> /// <param name="localPort">An integer specifying the local port to bind the socket to.</param> /// <returns>An implementation of the <see cref="IUdpSocket"/> interface used by RSSDP components to perform socket operations.</returns> - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The purpose of this method is to create and returns a disposable result, it is up to the caller to dispose it when they are done with it.")] - public IUdpSocket CreateUdpSocket(int localPort) + public IUdpSocket CreateSsdpUdpSocket(int localPort) { if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); - var retVal = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); + var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); try { retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), _LocalIP)); - return new UdpSocket(retVal, localPort, _LocalIP.ToString()); + return new UdpSocket(retVal, localPort, _LocalIP); } catch { @@ -70,7 +92,6 @@ namespace Emby.Common.Implementations.Net /// <param name="multicastTimeToLive">The multicast time to live value for the socket.</param> /// <param name="localPort">The number of the local port to bind to.</param> /// <returns></returns> - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "ip"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The purpose of this method is to create and returns a disposable result, it is up to the caller to dispose it when they are done with it.")] public IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) { if (ipAddress == null) throw new ArgumentNullException("ipAddress"); @@ -97,7 +118,7 @@ namespace Emby.Common.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), _LocalIP)); retVal.MulticastLoopback = true; - return new UdpSocket(retVal, localPort, _LocalIP.ToString()); + return new UdpSocket(retVal, localPort, _LocalIP); } catch { diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs index 86ce9c83b..d999d3fe8 100644 --- a/Emby.Common.Implementations/Net/UdpSocket.cs +++ b/Emby.Common.Implementations/Net/UdpSocket.cs @@ -17,26 +17,20 @@ namespace Emby.Common.Implementations.Net #region Fields - private System.Net.Sockets.Socket _Socket; + private Socket _Socket; private int _LocalPort; #endregion #region Constructors - public UdpSocket(System.Net.Sockets.Socket socket, int localPort, string ipAddress) + public UdpSocket(Socket socket, int localPort, IPAddress ip) { if (socket == null) throw new ArgumentNullException("socket"); _Socket = socket; _LocalPort = localPort; - IPAddress ip = null; - if (String.IsNullOrEmpty(ipAddress)) - ip = IPAddress.Any; - else - ip = IPAddress.Parse(ipAddress); - _Socket.Bind(new IPEndPoint(ip, _LocalPort)); if (_LocalPort == 0) _LocalPort = (_Socket.LocalEndPoint as IPEndPoint).Port; @@ -46,18 +40,18 @@ namespace Emby.Common.Implementations.Net #region IUdpSocket Members - public Task<ReceivedUdpData> ReceiveAsync() + public Task<SocketReceiveResult> ReceiveAsync() { ThrowIfDisposed(); - var tcs = new TaskCompletionSource<ReceivedUdpData>(); + var tcs = new TaskCompletionSource<SocketReceiveResult>(); - System.Net.EndPoint receivedFromEndPoint = new IPEndPoint(IPAddress.Any, 0); + EndPoint receivedFromEndPoint = new IPEndPoint(IPAddress.Any, 0); var state = new AsyncReceiveState(_Socket, receivedFromEndPoint); state.TaskCompletionSource = tcs; #if NETSTANDARD1_6 - _Socket.ReceiveFromAsync(new System.ArraySegment<Byte>(state.Buffer), System.Net.Sockets.SocketFlags.None, state.EndPoint) + _Socket.ReceiveFromAsync(new ArraySegment<Byte>(state.Buffer),SocketFlags.None, state.EndPoint) .ContinueWith((task, asyncState) => { if (task.Status != TaskStatus.Faulted) @@ -68,28 +62,36 @@ namespace Emby.Common.Implementations.Net } }, state); #else - _Socket.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, System.Net.Sockets.SocketFlags.None, ref state.EndPoint, new AsyncCallback(this.ProcessResponse), state); + _Socket.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.EndPoint, new AsyncCallback(this.ProcessResponse), state); #endif return tcs.Task; } - public Task SendTo(byte[] messageData, IpEndPointInfo endPoint) + public Task SendAsync(byte[] buffer, int size, IpEndPointInfo endPoint) { ThrowIfDisposed(); - if (messageData == null) throw new ArgumentNullException("messageData"); + if (buffer == null) throw new ArgumentNullException("messageData"); if (endPoint == null) throw new ArgumentNullException("endPoint"); #if NETSTANDARD1_6 - _Socket.SendTo(messageData, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port)); + + if (size != buffer.Length) + { + byte[] copy = new byte[size]; + Buffer.BlockCopy(buffer, 0, copy, 0, size); + buffer = copy; + } + + _Socket.SendTo(buffer, new IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port)); return Task.FromResult(true); #else var taskSource = new TaskCompletionSource<bool>(); try { - _Socket.BeginSendTo(messageData, 0, messageData.Length, SocketFlags.None, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port), result => + _Socket.BeginSendTo(buffer, 0, size, SocketFlags.None, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port), result => { try { @@ -100,29 +102,10 @@ namespace Emby.Common.Implementations.Net { taskSource.TrySetException(ex); } - catch (ObjectDisposedException ex) - { - taskSource.TrySetException(ex); - } - catch (InvalidOperationException ex) - { - taskSource.TrySetException(ex); - } - catch (SecurityException ex) - { - taskSource.TrySetException(ex); - } + }, null); } - catch (SocketException ex) - { - taskSource.TrySetException(ex); - } - catch (ObjectDisposedException ex) - { - taskSource.TrySetException(ex); - } - catch (SecurityException ex) + catch (Exception ex) { taskSource.TrySetException(ex); } @@ -151,7 +134,6 @@ namespace Emby.Common.Implementations.Net #region Private Methods - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Exceptions via task methods should be reported by task completion source, so this should be ok.")] private static void ProcessResponse(AsyncReceiveState state, Func<int> receiveData) { try @@ -160,11 +142,11 @@ namespace Emby.Common.Implementations.Net var ipEndPoint = state.EndPoint as IPEndPoint; state.TaskCompletionSource.SetResult( - new ReceivedUdpData() + new SocketReceiveResult() { Buffer = state.Buffer, ReceivedBytes = bytesRead, - ReceivedFrom = ToIpEndPointInfo(ipEndPoint) + RemoteEndPoint = ToIpEndPointInfo(ipEndPoint) } ); } @@ -204,7 +186,6 @@ namespace Emby.Common.Implementations.Net }; } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Exceptions via task methods should be reported by task completion source, so this should be ok.")] private void ProcessResponse(IAsyncResult asyncResult) { #if NET46 @@ -215,11 +196,11 @@ namespace Emby.Common.Implementations.Net var ipEndPoint = state.EndPoint as IPEndPoint; state.TaskCompletionSource.SetResult( - new ReceivedUdpData() + new SocketReceiveResult { Buffer = state.Buffer, ReceivedBytes = bytesRead, - ReceivedFrom = ToIpEndPointInfo(ipEndPoint) + RemoteEndPoint = ToIpEndPointInfo(ipEndPoint) } ); } @@ -247,7 +228,7 @@ namespace Emby.Common.Implementations.Net private class AsyncReceiveState { - public AsyncReceiveState(System.Net.Sockets.Socket socket, EndPoint endPoint) + public AsyncReceiveState(Socket socket, EndPoint endPoint) { this.Socket = socket; this.EndPoint = endPoint; @@ -256,9 +237,9 @@ namespace Emby.Common.Implementations.Net public EndPoint EndPoint; public byte[] Buffer = new byte[8192]; - public System.Net.Sockets.Socket Socket { get; private set; } + public Socket Socket { get; private set; } - public TaskCompletionSource<ReceivedUdpData> TaskCompletionSource { get; set; } + public TaskCompletionSource<SocketReceiveResult> TaskCompletionSource { get; set; } } |
