Я учусь некоторым простым сетевым технологиям с использованием Unity и Sockets, и у меня возникают проблемы с синхронизацией данных между клиентом и сервером. Я знаю, что есть и другие варианты использования Unity Networking, но, прежде чем двигаться дальше, я хочу лучше понять, как улучшить свой код с помощью системных библиотек.
В этом примере я просто пытаюсь выполнить потоковую передачу мое положение мыши над сокетом многоадресной рассылки UDP. Я кодирую строку в массив байтов и отправляю этот массив один раз за кадр. Я знаю, что отправка этих значений в виде строки неоптимальна, но, если это не является узким местом, я предполагаю, что все в порядке, вернитесь, чтобы оптимизировать это позже.
Я мой сервер настройки отправляет значения со скоростью 60 кадров в секунду, и клиент читает с той же скоростью. У меня проблема в том, что когда клиент получает значения, он обычно получает сразу несколько значений. Если я регистрирую полученные значения с помощью -----
между каждым кадром, я обычно получаю следующий результат:
------
------
------
------
------
------
------
119,396
91,396
45,391
18,379
-8,362
-35,342
-59,314
------
------
------
------
------
------
------
Я ожидал бы, что несинхронизированные циклы обновления приведут к получению двух значений на кадр, но я не уверен, чем может объясняться большее несоответствие.
Вот код сервера:
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class Server : MonoBehaviour
{
Socket _socket;
void OnEnable ()
{
var ip = IPAddress.Parse ("224.5.6.7");
var ipEndPoint = new IPEndPoint(ip, 4567);
_socket = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption (ip));
_socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2);
_socket.Connect(ipEndPoint);
}
void OnDisable ()
{
if (_socket != null)
{
_socket.Close();
_socket = null;
}
}
public void Send (string message)
{
var byteArray = Encoding.ASCII.GetBytes (message);
_socket.Send (byteArray);
}
}
И клиент:
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class Client : MonoBehaviour
{
Socket _socket;
byte[] _byteBuffer = new byte[16];
public delegate void MessageRecievedEvent (string message);
public MessageRecievedEvent messageWasRecieved = delegate {};
void OnEnable ()
{
var ipEndPoint = new IPEndPoint(IPAddress.Any, 4567);
var ip = IPAddress.Parse("224.5.6.7");
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_socket.Bind (ipEndPoint);
_socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip,IPAddress.Any));
}
void Update ()
{
while (_socket.Available > 0)
{
for (int i = 0; i < _byteBuffer.Length; i++) _byteBuffer[i] = 0;
_socket.Receive (_byteBuffer);
messageWasRecieved (Encoding.ASCII.GetString (_byteBuffer));
}
}
}
Если кто-нибудь может пролить свет на то, что я могу сделать для улучшения синхронизации, будет большим подспорьем.