首页 文章

发送UDP消息有效,在Unity3d上不接收C#

提问于
浏览
0

你好,

我试图在Unity3d中 Build 一个UDP连接,它在过去几天给了我一些头条:

我正在运行的Unity脚本应该接收并且可能在将来发送UDP消息 . Unity旁边我使用Wireshark跟踪数据包,使用PacketSender生成和接收UDP消息 .

消息源是一个PLC,每秒发送一个包,包含两个浮点数(8个字节)进行测试 . PLC IP为 192.168.0.1 ,它通过以太网直接连接到运行Unity的笔记本电脑 . (没有开关,没有路由器)

我的以太网端口具有IP 192.168.0.41 ,并且消息通过端口8052进入 .

通过以下方式我可以在Wireshark中看到:

  • 从PLC到Unity的软件包

  • 包从Unity离开到PLC

  • 包具有预期的结构

我在PacketSender中可以看到/做的事情:

来自PLC的

  • 包(通过端口8052)

  • 向Wireshark中可见的PLC发送消息

  • 通过接收这里的包,它也应该是安全的说防火墙端口窗口的工作原理 .

  • 如果我已经启动了Unity-receive脚本,我无法收到PacketSender的软件包......

...应该是一个指示器,Unity UDP套接字已启动并正在运行,希望吞下消息 . 如果我拨打 netstat -aon ,我可以在预期的端口和IP上看到Unity UPD进程; 0.0.0.0:8052192.168.0.41:8052 ,具体取决于其创建方式 . 此外,我可以看到没有其他进程使用相同的端口 .

But what does not work is to actually receive and use the data in my Unity script.

有效的方法是从另一个Unity脚本接收通过本地IP 127.0.0.1发送的数据 .

到目前为止,我已经尝试了几种方法来创建套接字:

var udpClient = new UdpClient(8052,AddressFamily.InterNetwork)
var udpClient = new UdpClient(8052)
UdpClient udpClient = new UdpClient(8052,AddressFamily.InterNetwork)
var udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

我试过了...

  • ...接收同步或异步消息

  • ...在主线程或后台线程中运行receive-loop

  • ...来禁用/禁用客户端阻止

  • ...将客户端绑定到IP或将其保留在IPAddress.Any上

  • ...关闭以太网端口上的HyperV交换机(仍然关闭)

  • ...打开防火墙中的相关端口

  • ...重启笔记本电脑

  • ...关于我能在任何论坛找到的每个解决方案 .

感觉就像C#套接字和Step7套接字说不同的UDP或C#套接字在接收端没有按预期运行 . 包裹真的在插座的门口,它忽略了它 .


设置规格:PLC:CPU315-2 PN / DP笔记本电脑:戴尔Latitude,i5,8GB内存,Win10企业版,64位Unity:Unity 2017.3.1f1,只有资产是PlayMaker


目前的测试代码:

using System;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
using System.Threading;


public class UDPReceive03 : MonoBehaviour
{
    Thread receiveThread;
    public UdpClient socket;
    private bool canReceive;
    public static bool messageReceived;
    public String statusThread;

    public int UDP_LISTEN_PORT;

    private int alive;

    // Use this for initialization
    void Start()
    {
        UDP_LISTEN_PORT = 8052;
        print("started");
        canReceive = true;
        messageReceived = false;


        alive = 0;

        receiveThread = new Thread(new ThreadStart(ReceiveData));
        receiveThread.IsBackground = true;
        receiveThread.Start();
    }

    // Update is called once per frame
    void Update()
    {
        // I know the code below is ugly, but that was my rebellion agains the situation
        statusThread = (canReceive) ? "Waiting" : "Busy";

        if (alive % 180 == 0)
            sendResponse(1);

        alive = (alive<180) ? alive + 1 : 1;
    }

    private void ReceiveData()
    {
        using (var udpClient = new UdpClient(8052,AddressFamily.InterNetwork))
        {
            int loggingEvent = 0;
            while (true)
            {
                print("started to receive");
                IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                var receivedResults = udpClient.Receive(ref remoteEndPoint);
                loggingEvent += receivedResults.Length;
                print("Success, received " + loggingEvent.ToString() + " bytes.");
                sendResponse(loggingEvent);
            }
        }
    }


    private void sendResponse(int count)
    {
        socket = new UdpClient(8051);
        // sending data
        IPEndPoint target = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 2000);
        // send a couple of sample messages:
        for (int num = 1; num <= count; num++)
        {
            byte[] message = new byte[num];
            socket.Send(message, message.Length, target);
        }
        socket.Close();
    }
}

我知道代码中缺少注释,但正如您可能已经猜到的那样,代码最近发生了很大变化 .

感谢您的帮助 .

1 回答

  • 0

    因此,经过一段非常令人沮丧的旅程后,我发现了一个不太好的解决办法,但是完成工作:

    我写了一个python脚本,打开一个套接字,接收外部数据并通过本地IP转发给Unity . 这很有效 .

    这是代码:

    # Import libraies
    import socket
    import time
    
    # Set send IP adress and port
    UDP_IP = "127.0.0.1"
    UDP_PORT_Rec = 8052
    UDP_PORT_Unity = 8055
    
    print("Receiving on Port:" + str(UDP_PORT_Rec))
    print("Sending to IP:" + UDP_IP + ":" + str(UDP_PORT_Unity))
    
    # Set socket to send udp messages and bind port
    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sock.bind(('',UDP_PORT_Rec));
    
    ## Keep sending message from file location
    while True:
        data, addr = sock.recvfrom(1024) #buffer size, hopefully no problem if too big
        print("Received")
    
        sock.sendto(data, (UDP_IP, UDP_PORT_Unity))
        print("Send")
    

    对您的故障排除有用的工具:

    • 安装Wireshark!它可能是跟踪互联网流量的最佳工具 . 对于普通应用程序,Wireshark中可见的包可能不可见!

    • 使用Packet Sender生成和接收流量 . 该应用程序使用基本方法来接收包 - 如果可以,那么您的程序也应该能够 .

    • 如果套接字正在运行,请检查 netstat -aon .

    • 完成:检查防火墙设置 .

相关问题