Здравствуйте,
Я пытаюсь установить UDP-соединение в Unity3d, и в последние дни у меня возникают некоторые проблемы:
Предполагается, что выполняемый мной сценарий Unity получити, возможно, в будущем отправлять UDP-сообщения.Рядом с Unity я использую Wireshark для отслеживания пакетов и PacketSender для генерации и получения сообщений UDP.
Источником сообщений является ПЛК, который каждую секунду отправляет пакет, содержащий два числа с плавающей запятой(8 байт) для тестирования.IP ПЛК - 192.168.0.1
, и он напрямую подключен через Ethernet к ноутбуку с Unity.(без коммутатора, без маршрутизатора)
Мой порт Ethernet имеет IP 192.168.0.41
, и сообщения поступают через порт 8052.
Что я вижу в Wireshark через:
- Пакеты, поступающие из ПЛК в Unity
- Пакеты, отправляемые из Unity в ПЛК
- Пакеты имеют ожидаемую структуру
Что я могусмотрите / делайте в PacketSender:
- пакеты, поступающие из ПЛК (через порт 8052)
- отправляют сообщения в ПЛК, которые видны в Wireshark
- , получаяпакеты здесь также можно с уверенностью сказать, что окно порта брандмауэра работает.
- Я НЕ МОГУ получать пакеты с PacketSender, если я уже запустил свой скрипт Unity-receive ...
... что должно быть индикатором того, что UDP-сокет Unity запущен и работает, мы надеемся проглотить сообщения.Если я позвоню netstat -aon
, я смогу увидеть процесс Unity UPD на ожидаемом порту и IP;0.0.0.0:8052
или 192.168.0.41:8052
, в зависимости от того, как он создан.Также я вижу, что ни один другой процесс не использует этот порт.
Но что не работает, так это фактический прием и использование данных в моем сценарии Unity.
Что работает, так это получение данных, отправляемых через локальный IP 127.0.0.1 из другого сценария Unity.
К настоящему времени я пробовал несколько способов создания сокета:
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);
Iпытался ...
- ... получать сообщения синхронные или асинхронные
- ... для запуска цикла приема в основном потоке или в фоновом потоке
- ... для включения / отключения блокировки клиента
- ... для привязки клиента к IP или оставления его на IP-адресе. Любой
- ... для закрытиявыключите коммутатор HyperV, который был у меня на порту Ethernet (все еще выключен)
- ..., чтобы открыть соответствующие порты в брандмауэре
- ..., чтобы перезагрузить ноутбук
- ... о каждом решении, которое я мог найти на любом форуме.
Такое чувство, что сокет C # и сокет Step7 говорят по-разномуUDP или C # сокет не работает на принимающей стороне, как ожидалось.Пакет действительно находится на пороге сокета и игнорирует его.
Характеристики установки: ПЛК: CPU315-2 PN / DP Портативный компьютер: Dell Latitude, i5, 8 ГБ ОЗУ, Win10 Enterprise, 64-бит Unity: Unity 2017.3.1f1, единственный актив - PlayMaker
Текущий тестовый код:
</p>
<code>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();
}
}
</code>
Мне известно об отсутствиикомментарии в коде, но, как вы уже догадались, в последнее время код сильно изменился.
Спасибо за помощь.