【问题标题】:Wake On Lan - Linux - .Net Core局域网唤醒 - Linux - .Net Core
【发布时间】:2017-10-24 00:19:37
【问题描述】:

我制作了一个小实用程序,可以向我网络上的计算机发送一个魔术包来唤醒它们。它在 Windows 上完美运行,但在 docker 容器 (linux) 中尝试同样的操作时,我得到了 ArgumentException

任何人都可以对此有所了解吗?它是 UDP 实现中的错误吗?是否与docker网络无法访问与主机在同一网络上的mac地址有关?

我的代码:

public async Task<int> SendWakeOnLanAsync(byte[] mac)
{
    Log.Information("Waking on MAC: {mac}", BitConverter.ToString(mac));

    int counter = 0;

    byte[] bytes = new byte[6 * 17];
    for (var i = 0; i < 6; i++)
    {
        bytes[counter++] = 0xFF;
    }

    //16x MAC
    for (var i = 0; i < 16; i++)
    {
        mac.CopyTo(bytes, 6 + i * 6);
    }

    try
    {
        using (var client = new UdpClient())
        {
            client.EnableBroadcast = true;
            return await client.SendAsync(bytes, bytes.Length, new IPEndPoint(new IPAddress(0xffffffff), 0));
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex, "Exception during wake on lan request.");
        throw;
    }
}

ArgumentException 跟踪:

   at System.Net.Sockets.Socket.DoBeginSendTo(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint endPointSnapshot, SocketAddress socketAddress, OverlappedAsyncResult asyncResult)
   at System.Net.Sockets.Socket.BeginSendTo(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint remoteEP, AsyncCallback callback, Object state)
   at System.Net.Sockets.UdpClient.BeginSend(Byte[] datagram, Int32 bytes, IPEndPoint endPoint, AsyncCallback requestCallback, Object state)
   at System.Net.Sockets.UdpClient.<>c.<SendAsync>b__53_0(Byte[] targetDatagram, Int32 targetBytes, IPEndPoint targetEndpoint, AsyncCallback callback, Object state)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2,TArg3](Func`6 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state, TaskCreationOptions creationOptions)
   at System.Threading.Tasks.TaskFactory`1.FromAsync[TArg1,TArg2,TArg3](Func`6 beginMethod, Func`2 endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state)
   at System.Net.Sockets.UdpClient.SendAsync(Byte[] datagram, Int32 bytes, IPEndPoint endPoint)
   at Asgard.WakeOnLan.Api.EthernetClient.<SendWakeOnLanAsync>d__0.MoveNext() in /builds/smarthome/Asgard.WakeOnLan.Api/src/Asgard.WakeOnLan.Api/EthernetClient.cs:line 42
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Asgard.WakeOnLan.Api.Controllers.WakeOnLanController.<Wake>d__2.MoveNext() in /builds/smarthome/Asgard.WakeOnLan.Api/src/Asgard.WakeOnLan.Api/Controllers/WakeOnLanController.cs:line 38
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.<RequestProcessingAsync>d__2.MoveNext()

【问题讨论】:

  • 尝试使用--net=host 和/或--privileged 运行您的容器。 Docker 在单独的网络堆栈中运行您的容器,并且默认情况下,它的功能比 root 在主机上的功能要少。
  • 这是 UDP 实现中的一个错误 公平地说,这是一个有据可查、久经考验的数据报包,可以追溯到 1980 年,怀疑它是一个错误。尝试查看您的代码,看看问题出在哪里。乍一看,这很突出,6 + i * 6 这是否意味着 6 + (i * 6) vs (6 + i) * 6 ?
  • 能够使用端口 0 进行复制(使用端口!= 0),我实际上得到了一个包装 SocketExceptionAggregateException
  • @t0mm13b:UDP 已经过很好的测试,但 Linux 上的 .NET Core 肯定不是。而且由于它可以在 Windows 上运行,我会假设至少在跨平台的实现方面存在差异。这是6 + (i*6)。我可以从 Windows 唤醒 PC,所以我对此很有信心。
  • @BMitch:准点。除了 Martin 对异常的修复(将端口更改为 7)之外,--net=host 确保数据包被发送到正确的位置。 --特权没有。谢谢!

标签: c# linux docker .net-core wake-on-lan


【解决方案1】:

这是因为并非所有系统都支持将 IP 包发送到端口 0。尝试改用 7 或 9(众所周知但大多未使用的端口)。

【讨论】:

  • 宾果游戏。它仍然不起作用,但我会将其归因于 docker 网络。但是更改端口消除了异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多