无法使用UdpClient捕获收到的数据报

时间:2018-09-13 19:02:09

标签: c# networking udp

我正在尝试向设备发送UDP命令,并从该设备接收UDP响应。发送正常。我可以看到数据报离开了(通过WireShark)。我还可以看到数据报从设备返回(再次通过WireShark)。命令离开与响应接收之间的周转时间约为15毫秒。

代码

Byte[] button_click(Byte[] command) 
{
    // Device exists at a particular IP address and listens for UDP commands on a particular port
    IPEndPoint SendingEndpoint = new IPEndPoint(DEVICE_IP, DEVICE_PORT);

    // Device always sends from port 32795 to whatever port the command originated from on my machine
    IPEndPoint ReceivingEndpoint = new IPEndPoint(DEVICE_IP, 32795);

    // Sending client
    sendingClient = new UdpClient();
    sendingClient.Connect(SendingEndpoint);

    // Receiving client
    receivingClient = new UdpClient();
    receivingClient.Client.ReceiveTimeout = RECEIVE_TIMEOUT; // timeout after 4 seconds
    receivingClient.Connect(receivingEndpoint);

    // Send command and wait for response
    Byte[] response = null;
    try
    {
        sendingClient.Connect(DEVICE_IP, DEVICE_PORT);
        sendingClient.Send(command, command.Length);
        response = receivingClient.Receive(ref receivingEndpoint);
    }
    catch (SocketException e)
    {
        // If we timeout, discard SocketException and return null response
    }

    return response;
}

问题

我无法在应用程序中捕获收到的数据报。运行上面的代码时,出现以下异常:

  

“连接尝试失败,因为连接方未   一段时间后正确响应或建立连接   失败,因为连接的主机无法响应。”

StackOverflow上有类似的帖子,但似乎都没有解决我的情况。而且我已经验证我的数据包没有在防火墙中被清除。

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

如果使用sendingClient进行接收,则可以获得正确的消息。原因是IP由主机+端口+协议组成,当发送点连接到设备并发送消息时,设备将接收端点以及与发送端点配对的UDP。当接收客户端尝试接收消息时,由于UDP是点对点的,因此不会发生任何事情,并且接收客户端的端口必须与发送客户端不同,因此,接收客户端什么也得不到。以下是我的示例代码供您参考。

        IPAddress address;
        IPAddress.TryParse("127.0.0.1", out address);
        IPEndPoint recPoint = new IPEndPoint(address, 13154);
        // IPEndPoint sendPoint = new IPEndPoint(address, 9999);
        UdpClient send = new UdpClient(9999);
        send.Connect(recPoint);
        Byte[] response = null;
        Byte[] command = System.Text.Encoding.Default.GetBytes("NO one");
        try
        {
            send.Send(command, command.Length);
            response = send.Receive(ref recPoint);
        }
        catch(Exception ex) {
            Console.WriteLine(ex.ToString());
        }

根据Alex的回答,我更新了完整的示例代码以供参考。

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Net;

namespace console
{
    class Program
    {
        static void Main(string[] args)
        {
            IPAddress address;
            IPAddress.TryParse("192.168.14.173", out address);
            IPEndPoint recPoint = new IPEndPoint(address, 13154);
            IPEndPoint recAnyPoint = new IPEndPoint(IPAddress.Any, 13154);
            IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("192.168.14.174"), 13154);

            // IPEndPoint sendPoint = new IPEndPoint(address, 9999);
            UdpClient send = new UdpClient();
            send.ExclusiveAddressUse = false;
            // no need to use the low level socketoption 
            // send.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            send.Client.Bind(recAnyPoint);
            send.Connect(ipPoint);
            UdpClient receive = new UdpClient();

            receive.ExclusiveAddressUse = false;
            // receive.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            receive.Client.Bind(recPoint);
            receive.Connect(ipPoint);
            Byte[] response = null;
            Byte[] command = System.Text.Encoding.Default.GetBytes("NO one");
            try
            {
                send.Send(command, command.Length);
                response = receive.Receive(ref ipPoint);
                Console.WriteLine(System.Text.Encoding.Default.GetString(response));
            }
            catch(Exception ex) {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}