Это проблема в основном из-за моей неопытности с winsock, сокетами, UDP и программированием в целом.По этой проблеме опубликовано много вопросов / ответов, но я не смог их просмотреть из-за своего плохого понимания winsock и т. Д., Чтобы понять, как решить мою проблему.
Проблема,В настоящее время у меня есть соединение UDP, работающее (непрерывно), правильно, через приложение C ++ и скрипт C #, работающий в приложении Unity.В настоящее время приложение C ++ преобразует информацию о положении с внешнего тактильного устройства в простую строку и отправляет эту дейтаграмму через UDP в приложение Unity.Затем сценарий Unity преобразует простую строку обратно в соответствующую информацию и используется для управления объектами в игровом пространстве Unity.Это прекрасно работает, но в основном потому, что я смог найти в Интернете сценарии, которые требовали лишь небольшого редактирования и настройки для работы с моим конкретным приложением.Теперь мне нужно отправить дейтаграммы из приложения Unity в приложение C ++ (обратное тому, что я сейчас делаю) для обеспечения тактильной обратной связи с тактильными устройствами, когда игровой объект взаимодействует с коллайдерами в игровом пространстве Unity.У меня есть данные, которые я хочу отправить, доступные при установлении контакта с коллайдерами (в настоящее время печатает через Debug.Log), но я не знаю, как правильно использовать функции Ssoto и Recvfrom из winsock, чтобы приложение C ++ активно слушало (не просто отправка), а приложение Unity активно отправляет (не просто прослушивает).
Я буду продолжать просматривать уже опубликованные вопросы / решения, чтобы выяснить, смогу ли я это выяснить, но в то же время, если кто-то сможет оказать некоторую помощь, я был бы очень признателен.Соответствующие части кода, который я использую, размещены ниже:
Этот скрипт прикреплен к моему игровому объекту в Unity
using UnityEngine;
using System.Collections;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Globalization;
using UnityEngine.Serialization;
public class TestUDPConnection : MonoBehaviour
{
private const int listenPort = 11000;
private UdpClient listener;
private IPEndPoint remoteIpEndPoint;
public static string currentUDPData;
private Thread listenerThread;
public bool inputSignal = false;
//bool to fix unity crash
public int fixMe = 1;
// Use this for initialization
void Start ()
{
// Creat a new thread for receiving UDP messages
listenerThread = new Thread(new ThreadStart(UDPReceive));
listenerThread.Name = "UDP Receiving Thread";
listenerThread.IsBackground = true; // run thread in background
listenerThread.Start();
}
// Thread for receiving UDP input
public void UDPReceive()
{
Debug.Log("Start receiving UDP.");
listener = new UdpClient(listenPort); // Initializes and BINDS directly (this is an overload of the UdpClient function, or to be precise the Constructor)
while (fixMe > 0) {
try {
// Opening udpclient listener on port
Debug.Log("Listening to port: " + listenPort);
// Receive bytes
remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); // Initializes the Endpoint with the correct Port and any IP address (UDP is connectionless the receiver doesn't need any IP address)
byte[] receiveBytes = listener.Receive(ref remoteIpEndPoint);
// Encode bytes to string (with UTF8 or ASCII Encoding)
currentUDPData = Encoding.ASCII.GetString(receiveBytes);
try {
//code is parsed here
} catch (Exception parseError) {
Debug.Log("Parsing didn't work: " + parseError.ToString());
}
} catch (Exception e) {
Debug.Log("Something went wrong: " + e.ToString());
}
}
Debug.Log("Stop receiving UDP.");
}
// Update is called once per frame
void Update ()
{
// Executed when BACKSPACE key hit
if (Input.GetKeyDown("backspace")) {
DestroyObject(gameObject);
fixMe = 0;
}
}
// Executed when object gets destroyed
void OnDisable()
{
if (listenerThread != null) {
listenerThread.Abort();
}
listener.Close();
Debug.Log("UDP receiver closed");
fixMe = 0;
}
}
Это скрипт, который я имею в своем приложении C ++ (тамв скрипте больше кода, который имеет дело с тактильным устройством, но эта часть относится к связи UDP):
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <vector>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int iResult;
WSADATA wsaData;
SOCKET SendSocket = INVALID_SOCKET;
sockaddr_in RecvAddr;
unsigned short Port = 11000; //port communicated through
char SendBuf[1024]; //message variable
int BufLen = 1024; //max length of buffer
int main()
{
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
//return 1;
}
//---------------------------------------------
// Create a socket for sending data
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SendSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
//return 1;
}
//---------------------------------------------
// Set up the RecvAddr structure with the IP address of
// the receiver (in this example case "192.168.1.1")
// and the specified port number.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//InetPton(AF_INET, _T("127.0.0.1"), &RecvAddr.sin_addr.s_addr);
//---------------------------------------------
// Clean up and quit.
//wprintf(L"Exiting.\n");
//WSACleanup();
//return 0;
//the udp communication, data parsing, etc., is contained within this loop:
// main haptic simulation loop
while (simulationRunning)
{
//script here for various stuff...
//taking in position values of haptic device in different variables
//converting them to strings
//adding them to the pBuffer that is sent through the UDP pipeline via:
iResult = sendto(SendSocket,
pBuffer, nStrSize + 1, 0, (SOCKADDR *)& RecvAddr, sizeof(RecvAddr));
if (iResult == SOCKET_ERROR) {
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
closesocket(SendSocket);
WSACleanup();
//return 1;
}
}
Так что, в принципе, я хотел бы реализовать обратное тому, что происходит в каждомкод (т.е. отправка данных в сценарии C # Unity и получение данных в сценарии приложения C ++).Из того, что я прочитал, вы можете отправлять / получать по одному и тому же сокету, так что может показаться, что было бы просто добавить несколько строк в мой цикл моделирования C ++, который включает функцию recvfrom, и несколько простых операций копирования и вставки моего цикла c ++в сценарий C # (с небольшими изменениями), чтобы получить отправленные данные.Я буду читать больше и пробовать другой код, чтобы узнать, как он будет работать в это время.Заранее благодарим за любую помощь, которую вы можете оказать!