您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
470 行
18 KiB
470 行
18 KiB
using System;
|
|
using System.Threading;
|
|
using System.Net;
|
|
using NUnit.Framework;
|
|
|
|
using System.Net.Sockets;
|
|
|
|
using Unity.Networking.Transport;
|
|
using Unity.Collections;
|
|
using Unity.Networking.Transport.LowLevel.Unsafe;
|
|
using Unity.Sample.Core;
|
|
using ExperimentalEventType = Unity.Networking.Transport.NetworkEvent.Type;
|
|
|
|
namespace TransportTests
|
|
{
|
|
public class SocketTests
|
|
{
|
|
[Test]
|
|
public void UdpC_BindToEndpoint_ReturnSocketHandle()
|
|
{
|
|
using (var socket = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var socketError = socket.Bind(NetworkEndPoint.AnyIpv4);
|
|
|
|
Assert.AreEqual(socketError, (int)SocketError.Success);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UdpC_BindMultipleToSameEndpoint_ReturnSocketError()
|
|
{
|
|
using (var first = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var second = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var endpoint = NetworkEndPoint.CreateIpv4(0, 50001);
|
|
|
|
var socketError = first.Bind(endpoint);
|
|
Assert.AreEqual(socketError, (int)SocketError.Success);
|
|
|
|
var error = second.Bind(endpoint);
|
|
Assert.AreEqual(error, (int)SocketError.AddressAlreadyInUse);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[Ignore("https://favro.com/organization/c564ede4ed3337f7b17986b6/215d676dd474c0744d2574f8?card=Uni-90284")]
|
|
public void UdpC_ListenThenConnect_ShouldFail()
|
|
{
|
|
using (var socket = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var endpoint = NetworkEndPoint.CreateIpv4(0, 50007);
|
|
socket.Bind(endpoint);
|
|
|
|
socket.Listen();
|
|
|
|
var error = Assert.Throws<SocketException>(() => { socket.Connect(endpoint); });
|
|
Assert.AreEqual(error.SocketErrorCode, SocketError.AddressNotAvailable);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UdpC_ConnectTest_ShouldConnect()
|
|
{
|
|
using (var server = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var serverPort = 50009;
|
|
|
|
server.Bind(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
client.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
|
|
server.Listen();
|
|
|
|
var id = client.Connect(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
|
|
NetworkConnection serverConnection, clientConnection;
|
|
int maxIterations = 100;
|
|
|
|
ConnectTogether(server, client, maxIterations, out serverConnection, out clientConnection);
|
|
Assert.AreEqual(id, serverConnection);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UdpC_MultipleConnectTest_ShouldConnect()
|
|
{
|
|
using (var server = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client0 = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client1 = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client2 = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client3 = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var serverPort = 50005;
|
|
|
|
server.Bind(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));//new IPEndPoint(IPAddress.Loopback, serverPort));
|
|
client0.Bind(NetworkEndPoint.LoopbackIpv4);// new IPEndPoint(IPAddress.Loopback, 0));
|
|
client1.Bind(NetworkEndPoint.LoopbackIpv4);//new IPEndPoint(IPAddress.Loopback, 0));
|
|
client2.Bind(NetworkEndPoint.LoopbackIpv4);//new IPEndPoint(IPAddress.Loopback, 0));
|
|
client3.Bind(NetworkEndPoint.LoopbackIpv4);//new IPEndPoint(IPAddress.Loopback, 0));
|
|
|
|
server.Listen();
|
|
|
|
NetworkConnection serverConnection, clientConnection;
|
|
int maxIterations = 100;
|
|
|
|
|
|
var endpoint = NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort);
|
|
var id = client0.Connect(endpoint);
|
|
ConnectTogether(server, client0, maxIterations, out serverConnection, out clientConnection);
|
|
Assert.AreEqual(id, serverConnection);
|
|
|
|
id = client1.Connect(endpoint);
|
|
ConnectTogether(server, client1, maxIterations, out serverConnection, out clientConnection);
|
|
Assert.AreEqual(id, serverConnection);
|
|
|
|
id = client2.Connect(endpoint);
|
|
ConnectTogether(server, client2, maxIterations, out serverConnection, out clientConnection);
|
|
Assert.AreEqual(id, serverConnection);
|
|
|
|
id = client3.Connect(endpoint);
|
|
ConnectTogether(server, client3, maxIterations, out serverConnection, out clientConnection);
|
|
Assert.AreEqual(id, serverConnection);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UdpC_ConnectSendTest_ShouldConnectAndReceiveData()
|
|
{
|
|
using (var server = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var serverPort = 50008;
|
|
|
|
server.Bind(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
client.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
|
|
server.Listen();
|
|
|
|
client.Connect(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
|
|
NetworkConnection serverConnection, clientConnection;
|
|
int maxIterations = 100;
|
|
|
|
ConnectTogether(server, client, maxIterations, out serverConnection, out clientConnection);
|
|
|
|
var message = new byte[]
|
|
{
|
|
(byte)'m',
|
|
(byte)'e',
|
|
(byte)'s',
|
|
(byte)'s',
|
|
(byte)'a',
|
|
(byte)'g',
|
|
(byte)'e'
|
|
};
|
|
|
|
SendReceive(client, server, clientConnection, serverConnection, message, maxIterations);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UdpC_ReconnectAndResend_ShouldReconnectAndResend()
|
|
{
|
|
using (var server = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
using (var client = new UdpNetworkDriver(new NetworkDataStreamParameter {}))
|
|
{
|
|
var serverPort = 50007;
|
|
|
|
server.Bind(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
client.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
|
|
server.Listen();
|
|
|
|
NetworkConnection serverConnection, clientConnection;
|
|
int maxIterations = 100;
|
|
|
|
var id = client.Connect(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
ConnectTogether(server, client, maxIterations, out serverConnection, out clientConnection);
|
|
|
|
client.Disconnect(id);
|
|
|
|
server.ScheduleUpdate().Complete();
|
|
|
|
var data = new byte[1472];
|
|
var size = 1472;
|
|
NetworkConnection from;
|
|
|
|
Assert.AreEqual(ExperimentalEventType.Disconnect, PollEvent(ExperimentalEventType.Disconnect, maxIterations, server, ref data, out size, out from));
|
|
|
|
id = client.Connect(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
ConnectTogether(server, client, maxIterations, out serverConnection, out clientConnection);
|
|
|
|
var message = new byte[]
|
|
{
|
|
(byte)'m',
|
|
(byte)'e',
|
|
(byte)'s',
|
|
(byte)'s',
|
|
(byte)'a',
|
|
(byte)'g',
|
|
(byte)'e'
|
|
};
|
|
|
|
SendReceive(client, server, clientConnection, serverConnection, message, maxIterations);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
//[Ignore("https://favro.com/organization/c564ede4ed3337f7b17986b6/215d676dd474c0744d2574f8?card=Uni-90284")]
|
|
public void UdpC_Timeout_ShouldDisconnect()
|
|
{
|
|
int customTimeout = 1000;
|
|
|
|
var config = new NetworkConfigParameter {
|
|
maxConnectAttempts = NetworkParameterConstants.MaxConnectAttempts,
|
|
connectTimeoutMS = NetworkParameterConstants.ConnectTimeoutMS,
|
|
disconnectTimeoutMS = customTimeout,
|
|
};
|
|
|
|
using (var server = new UdpNetworkDriver(config))
|
|
using (var client = new UdpNetworkDriver(config))
|
|
{
|
|
var serverPort = 50006;
|
|
|
|
server.Bind(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
client.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
|
|
server.Listen();
|
|
|
|
var id = client.Connect(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
|
|
NetworkConnection serverConnection, clientConnection;
|
|
int maxIterations = 100;
|
|
|
|
ConnectTogether(server, client, maxIterations, out serverConnection, out clientConnection);
|
|
Assert.AreEqual(id, serverConnection);
|
|
|
|
// Force timeout
|
|
Thread.Sleep(customTimeout + 500);
|
|
|
|
var message = new DataStreamWriter(7, Allocator.Persistent);
|
|
message.Write((byte)'m');
|
|
message.Write((byte)'e');
|
|
message.Write((byte)'s');
|
|
message.Write((byte)'s');
|
|
message.Write((byte)'a');
|
|
message.Write((byte)'g');
|
|
message.Write((byte)'e');
|
|
clientConnection.Send(server, message);
|
|
|
|
var data = new byte[1472];
|
|
int size = -1;
|
|
NetworkConnection from;
|
|
Assert.AreEqual(ExperimentalEventType.Disconnect, PollEvent(ExperimentalEventType.Disconnect, maxIterations, server, ref data, out size, out from));
|
|
Assert.AreEqual(from, clientConnection);
|
|
}
|
|
}
|
|
|
|
ExperimentalEventType PollEvent(ExperimentalEventType ev, int maxIterations, UdpNetworkDriver socket, ref byte[] buffer, out int size, out NetworkConnection connection)
|
|
{
|
|
int iterator = 0;
|
|
size = 0;
|
|
connection = default(NetworkConnection);
|
|
|
|
while (iterator++ < maxIterations)
|
|
{
|
|
DataStreamReader reader;
|
|
var context = default(DataStreamReader.Context);
|
|
ExperimentalEventType e;
|
|
if ((e = socket.PopEvent(out connection, out reader)) == ev)
|
|
{
|
|
if (reader.IsCreated)
|
|
{
|
|
reader.ReadBytesIntoArray(ref context, ref buffer, reader.Length);
|
|
size = reader.Length;
|
|
}
|
|
return e;
|
|
}
|
|
socket.ScheduleUpdate().Complete();
|
|
}
|
|
return ExperimentalEventType.Empty;
|
|
}
|
|
|
|
void SendReceive(UdpNetworkDriver sender, UdpNetworkDriver receiver, NetworkConnection from, NetworkConnection to, byte[] data, int maxIterations)
|
|
{
|
|
using (var writer = new DataStreamWriter(data.Length, Allocator.Persistent))
|
|
{
|
|
writer.Write(data, data.Length);
|
|
|
|
// sender.Send(to, writer); // old one preserved to explain how names were chosen :-)
|
|
to.Send(sender, writer); // new :-)
|
|
|
|
sender.ScheduleUpdate().Complete();
|
|
receiver.ScheduleUpdate().Complete();
|
|
|
|
var buffer = new byte[1472];
|
|
int size = 0;
|
|
NetworkConnection connection;
|
|
PollEvent(ExperimentalEventType.Data, maxIterations, receiver, ref buffer, out size, out connection);
|
|
|
|
Assert.AreEqual(from, connection);
|
|
Assert.AreEqual(data.Length, size);
|
|
|
|
for (int i = 0; i < data.Length; i++)
|
|
Assert.AreEqual(data[i], buffer[i]);
|
|
}
|
|
}
|
|
|
|
void ConnectTogether(UdpNetworkDriver server, UdpNetworkDriver client, int maxIterations, out NetworkConnection serverConnection, out NetworkConnection clientConnection)
|
|
{
|
|
int servers = 0, clients = 0, iterations = 0;
|
|
serverConnection = default(NetworkConnection);
|
|
clientConnection = default(NetworkConnection);
|
|
|
|
DataStreamReader reader;
|
|
|
|
NetworkConnection poppedConnection = default(NetworkConnection);
|
|
while (clients != 1 || servers != 1)
|
|
{
|
|
Assert.Less(iterations++, maxIterations);
|
|
|
|
server.ScheduleUpdate().Complete();
|
|
|
|
var newConnection = server.Accept();
|
|
if (newConnection != default(NetworkConnection))
|
|
{
|
|
clients++;
|
|
clientConnection = newConnection;
|
|
}
|
|
|
|
if (client.PopEvent(out poppedConnection, out reader) == ExperimentalEventType.Connect)
|
|
{
|
|
serverConnection = poppedConnection;
|
|
servers++;
|
|
}
|
|
|
|
client.ScheduleUpdate().Complete();
|
|
Assert.AreNotEqual(clientConnection, default(NetworkConnection));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UdpC_LongGoingTest()
|
|
{
|
|
using (UdpCClient server = new UdpCClient(12000))
|
|
using (UdpCClient c0 = new UdpCClient(12001, 12000))
|
|
using (UdpCClient c1 = new UdpCClient(12002, 12000))
|
|
using (UdpCClient c2 = new UdpCClient(12003, 12000))
|
|
using (UdpCClient c3 = new UdpCClient(12004, 12000))
|
|
using (UdpCClient c4 = new UdpCClient(12005, 12000))
|
|
using (UdpCClient c5 = new UdpCClient(12006, 12000))
|
|
{
|
|
long start = 0, now = 0;
|
|
start = NetworkUtils.stopwatch.ElapsedMilliseconds;
|
|
|
|
while (now - start < 30000)
|
|
{
|
|
server.Update();
|
|
c0.Update();
|
|
c1.Update();
|
|
c2.Update();
|
|
c3.Update();
|
|
c4.Update();
|
|
c5.Update();
|
|
now = NetworkUtils.stopwatch.ElapsedMilliseconds;
|
|
}
|
|
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", server.connectCounter,
|
|
server.disconnectCounter, server.dataCounter));
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", c0.connectCounter, c0.disconnectCounter,
|
|
c0.dataCounter));
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", c1.connectCounter, c1.disconnectCounter,
|
|
c1.dataCounter));
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", c2.connectCounter, c2.disconnectCounter,
|
|
c2.dataCounter));
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", c3.connectCounter, c3.disconnectCounter,
|
|
c3.dataCounter));
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", c4.connectCounter, c4.disconnectCounter,
|
|
c4.dataCounter));
|
|
GameDebug.Log(string.Format("con: {0}, disc {1}, data {2}", c5.connectCounter, c5.disconnectCounter,
|
|
c5.dataCounter));
|
|
}
|
|
}
|
|
}
|
|
|
|
public class UdpCClient : IDisposable
|
|
{
|
|
UdpNetworkDriver m_Socket;
|
|
|
|
NetworkConnection conn = default(NetworkConnection);
|
|
int serverPort;
|
|
|
|
public int connectCounter;
|
|
public int disconnectCounter;
|
|
public int dataCounter;
|
|
|
|
public UdpCClient(int port, int serverPort = -1)
|
|
{
|
|
m_Socket = new UdpNetworkDriver(new NetworkDataStreamParameter {});
|
|
m_Socket.Bind(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)port));
|
|
if (serverPort == -1)
|
|
m_Socket.Listen();
|
|
|
|
this.serverPort = serverPort;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (!m_Socket.Listening && !conn.IsCreated)
|
|
{
|
|
conn = m_Socket.Connect(NetworkEndPoint.CreateIpv4(0x7f000001, (ushort)serverPort));
|
|
}
|
|
else if (!m_Socket.Listening && dataCounter == 0 && !conn.IsCreated)
|
|
{
|
|
using (var message = new DataStreamWriter(7, Allocator.Persistent))
|
|
{
|
|
message.Write((byte)'m');
|
|
message.Write((byte)'e');
|
|
message.Write((byte)'s');
|
|
message.Write((byte)'s');
|
|
message.Write((byte)'a');
|
|
message.Write((byte)'g');
|
|
message.Write((byte)'e');
|
|
|
|
conn.Send(m_Socket, message);
|
|
}
|
|
}
|
|
else if (!m_Socket.Listening && conn.IsCreated &&
|
|
UnityEngine.Random.Range(0, 1000) < 10)
|
|
{
|
|
m_Socket.Disconnect(conn);
|
|
conn = default(NetworkConnection);
|
|
}
|
|
|
|
NetworkConnection connection;
|
|
DataStreamReader reader;
|
|
var context = default(DataStreamReader.Context);
|
|
var ev = m_Socket.PopEvent(out connection, out reader);
|
|
if (ev == ExperimentalEventType.Empty)
|
|
return;
|
|
|
|
using (var writer = new DataStreamWriter(reader.Length, Allocator.Temp))
|
|
{
|
|
unsafe
|
|
{
|
|
reader.ReadBytes(ref context, writer.GetUnsafePtr(), reader.Length);
|
|
}
|
|
switch (ev)
|
|
{
|
|
case ExperimentalEventType.Connect:
|
|
connectCounter++;
|
|
break;
|
|
case ExperimentalEventType.Disconnect:
|
|
conn = default(NetworkConnection);
|
|
disconnectCounter++;
|
|
break;
|
|
case ExperimentalEventType.Data:
|
|
dataCounter++;
|
|
connection.Send(m_Socket, writer);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
m_Socket.Dispose();
|
|
}
|
|
}
|
|
}
|