【问题标题】:C# Application not receiving packets on UDPClient.ReceiveC# 应用程序未在 UDPClient.Receive 上接收数据包
【发布时间】:2014-06-23 10:32:47
【问题描述】:

我遇到了一个我似乎无法调试的奇怪问题。我的应用程序从通过特定端口发送 UDP 数据包的设备接收数据包。设置好 UDP 侦听器后,while 循环会定期触发 Receive 命令。

我应该在每个给定的时间间隔收到 400 个值,我什至设置了一个流程来确保这些值通过。下面是相关代码的sn-p:

public UdpClient listener;

IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort); 
//where listenPort is an int holding the port values should be received from

listener.ExclusiveAddressUse = false;
listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
listener.Client.Bind(groupEP);

if (listener.Client.Connected)
{
     listener.Connect(groupEP);
}
//I've actually never seen the app actually enter the code contained above

try
{
    while (!done)
    {
        if (isListenerClosed == false && currentDevice.isConnected)
        {
             try
             {
                  receive_byte_array = listener.Receive(ref groupEP); 
             }
             catch (Exception ex)
             {
                  throw ex;
             }
        }
    }
}
catch (SocketException ex)
{
    throw ex;
}

奇怪的是,该应用程序在我的 PC 上运行良好(通过安装文件/Installshield 以及在 Visual Studio 中运行时),但在同事计算机上运行安装文件时不会收到任何数据(它运行在他的 Visual Studio 环境中就好了)。我还尝试将 Visual Studio 附加到应用程序的进程,在那里我发现代码运行良好,直到达到listener.Receive。没有捕获到异常,VS 中没有给出错误,但代码只是停止,因为没有收到数据。

顺便说一句,两台机器是相同的(运行 64 位 Windows 7 Ultimate N 的 Mac Mini)。

我什至在主程序中包含了一个 UnhandledExceptionHandler,如下所示:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    MessageBox.Show("Unhandled Exception Caught " + e.ToString());
    throw new NotImplementedException();
}

这可能是 Windows 中的应用程序权限问题吗?关于查明问题的最佳方法的任何想法?

【问题讨论】:

  • 可能是防火墙问题,您检查了吗?
  • 防火墙实际上似乎阻止了 UDP 连接,但没有阻止与 Internet 的连接。忽略它感到愚蠢。谢谢@oleksii!

标签: c# winforms udpclient


【解决方案1】:

UDP 是一种无连接协议。不要Connect。相反,您只是在传递数据包。此外,当您使用UdpClient 时,不要深入挖掘底层套接字。没有意义。

最简单(也很愚蠢)的 UDP 监听器看起来像这样:

var listener = new UdpClient(54323, AddressFamily.InterNetwork);

var ep = default(IPEndPoint);

while (!done)
{
    var data = listener.Receive(ref ep);

    // Process the data
}

围绕ExclusiveAddressUse(和SocketOptionName.ReuseAddress)做所有事情只会对你隐藏问题。除非您使用广播或多播,否则该端口上只有一个 UDP 侦听器会收到消息。这通常是一件坏事。

如果这个简单的代码不起作用,请检查管道。防火墙、IP 地址、驱动程序等。安装 WireShark 并检查 UDP 数据包是否真正通过 - 这可能是设备的问题,也可能是配置错误。

此外,理想情况下,您希望异步执行所有这些操作。如果您有 .NET 4.5,这实际上非常简单。

【讨论】:

  • 防火墙实际上是问题所在。我已经添加了ExclusiveAddressUse,因为在创建新侦听器(它是一个基于会话的应用程序)时我不断收到 socketExceptions。以这种方式连接并随后关闭连接似乎解决了我在结束一个会话并开始另一个会话时遇到的问题。我们之前确实在设备上遇到了一些问题。由于组件故障,我收到的数据包比预期的要少,但从那时起我已经仔细检查过它,一切都很好。我想知道该应用程序是否更值得防火墙信任
  • 默认情况下,Windows 防火墙会阻止几乎所有传入数据,就这么简单。如果您想更改它,您可以在安装程序中包含防火墙规则更改。这就是所有合适的服务器所做的:)当连接到互联网时,您正在创建一个出站连接(并且 TCP 是双向的,因此您根本不需要入站连接),这是默认允许的。
  • 这对我来说是正确的答案:不要调用Connect,而是在 Send() 函数中发送远程地址和端口,例如udpClient.Send(dgram, dgram.Length, remoteEndPoint);
【解决方案2】:

如果您在Windows Vista 或更高版本 上运行它,它可能是UAC。它可以悄悄地阻止套接字正常工作。如果您将UAC 级别调低,它不仅会阻塞套接字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多