您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
386 行
17 KiB
386 行
17 KiB
using System;
|
|
using System.Threading;
|
|
using AOT;
|
|
using NUnit.Framework;
|
|
using Unity.Networking.Transport.Utilities;
|
|
using Unity.Burst;
|
|
|
|
namespace Unity.Networking.Transport.Tests
|
|
{
|
|
[BurstCompile]
|
|
public unsafe struct TempDropPacketPipelineStage : INetworkPipelineStage
|
|
{
|
|
public static byte* s_StaticInstanceBuffer;
|
|
static TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate> ReceiveFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate>(Receive);
|
|
static TransportFunctionPointer<NetworkPipelineStage.SendDelegate> SendFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.SendDelegate>(Send);
|
|
static TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate> InitializeConnectionFunctionPointer = new TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate>(InitializeConnection);
|
|
public NetworkPipelineStage StaticInitialize(byte* staticInstanceBuffer, int staticInstanceBufferLength, INetworkParameter[] netParams)
|
|
{
|
|
s_StaticInstanceBuffer = staticInstanceBuffer;
|
|
*staticInstanceBuffer = 0;
|
|
return new NetworkPipelineStage(
|
|
Receive: ReceiveFunctionPointer,
|
|
Send: SendFunctionPointer,
|
|
InitializeConnection: InitializeConnectionFunctionPointer,
|
|
ReceiveCapacity: 0,
|
|
SendCapacity: 0,
|
|
HeaderCapacity: 0,
|
|
SharedStateCapacity: 0
|
|
);
|
|
}
|
|
public int StaticSize => 2;
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.ReceiveDelegate))]
|
|
private static void Receive(ref NetworkPipelineContext ctx, ref InboundRecvBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
|
|
{
|
|
byte idx = ctx.staticInstanceBuffer[1];
|
|
if (ctx.staticInstanceBuffer[0] == idx)
|
|
{
|
|
// Drop the packet
|
|
inboundBuffer = default;
|
|
}
|
|
*ctx.staticInstanceBuffer += 1;
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.SendDelegate))]
|
|
private static int Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
|
|
{
|
|
return (int)Error.StatusCode.Success;
|
|
}
|
|
|
|
[BurstCompile(DisableDirectCall = true)]
|
|
[MonoPInvokeCallback(typeof(NetworkPipelineStage.InitializeConnectionDelegate))]
|
|
private static void InitializeConnection(byte* staticInstanceBuffer, int staticInstanceBufferLength,
|
|
byte* sendProcessBuffer, int sendProcessBufferLength, byte* recvProcessBuffer, int recvProcessBufferLength,
|
|
byte* sharedProcessBuffer, int sharedProcessBufferLength)
|
|
{
|
|
}
|
|
}
|
|
public struct TempDropPacketPipelineStageCollection
|
|
{
|
|
public static void Register()
|
|
{
|
|
NetworkPipelineStageCollection.RegisterPipelineStage(new TempDropPacketPipelineStage());
|
|
}
|
|
}
|
|
|
|
public class FragmentationPipelineTests
|
|
{
|
|
private NetworkDriver m_ServerDriver;
|
|
private NetworkDriver m_ClientDriver;
|
|
|
|
[SetUp]
|
|
public void IPC_Setup()
|
|
{
|
|
TempDropPacketPipelineStageCollection.Register();
|
|
var timeoutParam = new NetworkConfigParameter
|
|
{
|
|
connectTimeoutMS = NetworkParameterConstants.ConnectTimeoutMS,
|
|
maxConnectAttempts = NetworkParameterConstants.MaxConnectAttempts,
|
|
disconnectTimeoutMS = 90 * 1000,
|
|
fixedFrameTimeMS = 16
|
|
};
|
|
m_ServerDriver =
|
|
TestNetworkDriver.Create(
|
|
new NetworkDataStreamParameter {size = 0},
|
|
timeoutParam,
|
|
new ReliableUtility.Parameters { WindowSize = 32 },
|
|
new FragmentationUtility.Parameters { PayloadCapacity = 4 * 1024 });
|
|
m_ServerDriver.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
m_ServerDriver.Listen();
|
|
m_ClientDriver =
|
|
TestNetworkDriver.Create(
|
|
new NetworkDataStreamParameter {size = 0},
|
|
timeoutParam,
|
|
new ReliableUtility.Parameters { WindowSize = 32 },
|
|
new SimulatorUtility.Parameters { MaxPacketCount = 30, MaxPacketSize = 16, PacketDelayMs = 0, /*PacketDropInterval = 8,*/ PacketDropPercentage = 10},
|
|
new FragmentationUtility.Parameters { PayloadCapacity = 4 * 1024 });
|
|
}
|
|
|
|
[TearDown]
|
|
public void IPC_TearDown()
|
|
{
|
|
m_ClientDriver.Dispose();
|
|
m_ServerDriver.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void NetworkPipeline_Fragmentation_SendRecvOnce()
|
|
{
|
|
var clientPipe = m_ClientDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
var serverPipe = m_ServerDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
|
|
// Connect to server
|
|
var clientToServer = m_ClientDriver.Connect(m_ServerDriver.LocalEndPoint());
|
|
Assert.AreNotEqual(default(NetworkConnection), clientToServer);
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
// Handle incoming connection from client
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
var serverToClient = m_ServerDriver.Accept();
|
|
Assert.AreNotEqual(default(NetworkConnection), serverToClient);
|
|
|
|
// Send message to client
|
|
if (m_ServerDriver.BeginSend(serverPipe, serverToClient, out var strm) == 0)
|
|
{
|
|
strm.WriteInt(42);
|
|
m_ServerDriver.EndSend(strm);
|
|
}
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
|
|
// Receive incoming message from server
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
DataStreamReader readStrm;
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
Assert.AreEqual(NetworkEvent.Type.Data, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
Assert.AreEqual(sizeof(int), readStrm.Length);
|
|
Assert.AreEqual(42, readStrm.ReadInt());
|
|
}
|
|
|
|
[Test]
|
|
public void NetworkPipeline_Fragmentation_SendRecvOversized()
|
|
{
|
|
var clientPipe = m_ClientDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
var serverPipe = m_ServerDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
|
|
// Connect to server
|
|
var clientToServer = m_ClientDriver.Connect(m_ServerDriver.LocalEndPoint());
|
|
Assert.AreNotEqual(default(NetworkConnection), clientToServer);
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
// Handle incoming connection from client
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
var serverToClient = m_ServerDriver.Accept();
|
|
Assert.AreNotEqual(default(NetworkConnection), serverToClient);
|
|
|
|
int messageSize = 3000;
|
|
int intCount = messageSize / sizeof(int);
|
|
|
|
// Send message to client
|
|
if (m_ServerDriver.BeginSend(serverPipe, serverToClient, out var strm, messageSize) == 0)
|
|
{
|
|
for (int i = 0; i < intCount; ++i)
|
|
{
|
|
strm.WriteInt(i);
|
|
}
|
|
m_ServerDriver.EndSend(strm);
|
|
}
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
|
|
// Receive incoming message from server
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
DataStreamReader readStrm;
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
Assert.AreEqual(NetworkEvent.Type.Data, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
|
|
Assert.AreEqual(messageSize, readStrm.Length);
|
|
for (int i = 0; i < intCount; ++i)
|
|
{
|
|
Assert.AreEqual(i, readStrm.ReadInt());
|
|
}
|
|
}
|
|
[Test]
|
|
public void NetworkPipeline_Fragmentation_SendRecvMaxSize()
|
|
{
|
|
var clientPipe = m_ClientDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
var serverPipe = m_ServerDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
|
|
// Connect to server
|
|
var clientToServer = m_ClientDriver.Connect(m_ServerDriver.LocalEndPoint());
|
|
Assert.AreNotEqual(default(NetworkConnection), clientToServer);
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
// Handle incoming connection from client
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
var serverToClient = m_ServerDriver.Accept();
|
|
Assert.AreNotEqual(default(NetworkConnection), serverToClient);
|
|
|
|
int messageSize = 4*1024-m_ServerDriver.MaxHeaderSize(serverPipe);
|
|
|
|
// Send message to client
|
|
if (m_ServerDriver.BeginSend(serverPipe, serverToClient, out var strm, messageSize) == 0)
|
|
{
|
|
for (int i = 0; i < messageSize; ++i)
|
|
{
|
|
strm.WriteByte((byte)i);
|
|
}
|
|
m_ServerDriver.EndSend(strm);
|
|
}
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
|
|
// Receive incoming message from server
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
DataStreamReader readStrm;
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
Assert.AreEqual(NetworkEvent.Type.Data, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
|
|
Assert.AreEqual(messageSize, readStrm.Length);
|
|
for (int i = 0; i < messageSize; ++i)
|
|
{
|
|
Assert.AreEqual((byte)i, readStrm.ReadByte());
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void NetworkPipeline_Fragmentation_DroppedPacket()
|
|
{
|
|
var clientPipe = m_ClientDriver.CreatePipeline(typeof(FragmentationPipelineStage),
|
|
typeof(TempDropPacketPipelineStage));
|
|
var serverPipe = m_ServerDriver.CreatePipeline(typeof(FragmentationPipelineStage));
|
|
|
|
// Connect to server
|
|
var clientToServer = m_ClientDriver.Connect(m_ServerDriver.LocalEndPoint());
|
|
Assert.AreNotEqual(default(NetworkConnection), clientToServer);
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
// Handle incoming connection from client
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
var serverToClient = m_ServerDriver.Accept();
|
|
Assert.AreNotEqual(default(NetworkConnection), serverToClient);
|
|
|
|
int messageSize = 3000;
|
|
int intCount = messageSize / sizeof(int);
|
|
int messageCount = 3;
|
|
|
|
int packetCount = -1;
|
|
for(int dropIndex = 0; dropIndex != packetCount; ++dropIndex)
|
|
{
|
|
TempDropPacketPipelineStage.s_StaticInstanceBuffer[0] = 0; // Reset packet counter
|
|
TempDropPacketPipelineStage.s_StaticInstanceBuffer[1] = (byte)dropIndex;
|
|
|
|
for (int j = 0; j < messageCount; ++j)
|
|
{
|
|
// Send one message
|
|
if (m_ServerDriver.BeginSend(serverPipe, serverToClient, out var strm, messageSize) == 0)
|
|
{
|
|
for (int i = 0; i < intCount; ++i)
|
|
{
|
|
strm.WriteInt(i);
|
|
}
|
|
|
|
m_ServerDriver.EndSend(strm);
|
|
}
|
|
}
|
|
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
packetCount = TempDropPacketPipelineStage.s_StaticInstanceBuffer[0];
|
|
|
|
{
|
|
// We have dropped one fragment. The result should be that one complete fragmented message
|
|
// is discarded, and the remaining messageCount - 1 are intact.
|
|
DataStreamReader readStrm;
|
|
NetworkEvent.Type eventType;
|
|
if (dropIndex == 0) // First pass only
|
|
{
|
|
eventType = clientToServer.PopEvent(m_ClientDriver, out readStrm);
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, eventType);
|
|
}
|
|
|
|
for (int j = 0; j < messageCount - 1; ++j)
|
|
{
|
|
eventType = clientToServer.PopEvent(m_ClientDriver, out readStrm);
|
|
Assert.AreEqual(NetworkEvent.Type.Data, eventType);
|
|
Assert.AreEqual(messageSize, readStrm.Length);
|
|
for (int i = 0; i < intCount; ++i)
|
|
{
|
|
Assert.AreEqual(i, readStrm.ReadInt());
|
|
}
|
|
}
|
|
|
|
Assert.AreEqual(NetworkEvent.Type.Empty, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
}
|
|
}
|
|
}
|
|
[Test]
|
|
public void NetworkPipeline_Fragmentation_Unreliable_SendRecv1380_Plus()
|
|
{
|
|
var clientPipe = m_ClientDriver.CreatePipeline(typeof(FragmentationPipelineStage), typeof(UnreliableSequencedPipelineStage));
|
|
var serverPipe = m_ServerDriver.CreatePipeline(typeof(FragmentationPipelineStage), typeof(UnreliableSequencedPipelineStage));
|
|
|
|
// Connect to server
|
|
var clientToServer = m_ClientDriver.Connect(m_ServerDriver.LocalEndPoint());
|
|
Assert.AreNotEqual(default(NetworkConnection), clientToServer);
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
// Handle incoming connection from client
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
var serverToClient = m_ServerDriver.Accept();
|
|
Assert.AreNotEqual(default(NetworkConnection), serverToClient);
|
|
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
DataStreamReader readStrm;
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
for (int messageSize = 1380; messageSize <= 1400; ++messageSize)
|
|
{
|
|
// Send message to client
|
|
if (m_ServerDriver.BeginSend(serverPipe, serverToClient, out var strm, messageSize) == 0)
|
|
{
|
|
for (int i = 0; i < messageSize; ++i)
|
|
{
|
|
strm.WriteByte((byte)i);
|
|
}
|
|
m_ServerDriver.EndSend(strm);
|
|
}
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
|
|
// Receive incoming message from server
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
Assert.AreEqual(NetworkEvent.Type.Data, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
|
|
Assert.AreEqual(messageSize, readStrm.Length);
|
|
for (int i = 0; i < messageSize; ++i)
|
|
{
|
|
Assert.AreEqual((byte)i, readStrm.ReadByte());
|
|
}
|
|
}
|
|
}
|
|
[Test]
|
|
public void NetworkPipeline_Unreliable_Fragmentation_SendRecv1380_Plus()
|
|
{
|
|
var clientPipe = m_ClientDriver.CreatePipeline(typeof(UnreliableSequencedPipelineStage), typeof(FragmentationPipelineStage));
|
|
var serverPipe = m_ServerDriver.CreatePipeline(typeof(UnreliableSequencedPipelineStage), typeof(FragmentationPipelineStage));
|
|
|
|
// Connect to server
|
|
var clientToServer = m_ClientDriver.Connect(m_ServerDriver.LocalEndPoint());
|
|
Assert.AreNotEqual(default(NetworkConnection), clientToServer);
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
|
|
// Handle incoming connection from client
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
var serverToClient = m_ServerDriver.Accept();
|
|
Assert.AreNotEqual(default(NetworkConnection), serverToClient);
|
|
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
DataStreamReader readStrm;
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
|
|
for (int messageSize = 1380; messageSize <= 1400; ++messageSize)
|
|
{
|
|
// Send message to client
|
|
if (m_ServerDriver.BeginSend(serverPipe, serverToClient, out var strm, messageSize) == 0)
|
|
{
|
|
for (int i = 0; i < messageSize; ++i)
|
|
{
|
|
strm.WriteByte((byte)i);
|
|
}
|
|
m_ServerDriver.EndSend(strm);
|
|
}
|
|
m_ServerDriver.ScheduleUpdate().Complete();
|
|
|
|
// Receive incoming message from server
|
|
m_ClientDriver.ScheduleUpdate().Complete();
|
|
Assert.AreEqual(NetworkEvent.Type.Data, clientToServer.PopEvent(m_ClientDriver, out readStrm));
|
|
|
|
Assert.AreEqual(messageSize, readStrm.Length);
|
|
for (int i = 0; i < messageSize; ++i)
|
|
{
|
|
Assert.AreEqual((byte)i, readStrm.ReadByte());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|