你好,
我试图在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:8052
或 192.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 回答
因此,经过一段非常令人沮丧的旅程后,我发现了一个不太好的解决办法,但是完成工作:
我写了一个python脚本,打开一个套接字,接收外部数据并通过本地IP转发给Unity . 这很有效 .
这是代码:
对您的故障排除有用的工具:
安装Wireshark!它可能是跟踪互联网流量的最佳工具 . 对于普通应用程序,Wireshark中可见的包可能不可见!
使用Packet Sender生成和接收流量 . 该应用程序使用基本方法来接收包 - 如果可以,那么您的程序也应该能够 .
如果套接字正在运行,请检查
netstat -aon
.完成:检查防火墙设置 .