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

时间:2018-05-28 06:20:47

标签: c# sockets unity3d udp

您好,

我正在尝试在Unity3d中设置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,我可以在预期的港口和地点看到Unity UPD流程。 IP; 0.0.0.0:8052192.168.0.41:8052,具体取决于其创建方式。此外,我可以看到没有其他进程使用相同的端口。

但不起作用的是在Unity脚本中实际接收和使用数据。

从另一个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(); } }

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

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

如果您想从外部源接收数据,您需要在防火墙上允许 Unity 或禁用防火墙。防火墙阻止了与外部源的统一编辑器连接,这就是您可以发送数据但无法接收数据的原因。如果你构建你的项目,你的代码就会工作,因为它会在第一次运行时询问你

enter image description here

答案 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核对。
  • 完成:检查防火墙设置。