Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion LiteNetLib.Tests/CommunicationTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -39,6 +41,7 @@ public void TearDown()

private const int DefaultPort = 9050;
private const string DefaultAppKey = "test_server";
private static readonly byte[] DefaultAppKeyBytes = new byte[] { 12, 0, 116, 101, 115, 116, 95, 115, 101, 114, 118, 101, 114 };

public NetManagerStack ManagerStack { get; set; }

Expand Down Expand Up @@ -79,6 +82,30 @@ public void P2PConnect()
Assert.AreEqual(1, client2.ConnectedPeersCount);
}

#if NET5_0_OR_GREATER
[Test, Timeout(TestTimeout)]
public void P2PConnectWithSpan()
{
var client1 = ManagerStack.Client(1);
var client2 = ManagerStack.Client(2);

IPEndPoint endPoint1 = new IPEndPoint(IPAddress.Loopback, client2.LocalPort);
IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Loopback, client1.LocalPort);
client1.Connect(endPoint1, DefaultAppKeyBytes.AsSpan());
client2.Connect(endPoint2, DefaultAppKeyBytes.AsSpan());

while (client1.ConnectedPeersCount != 1 || client2.ConnectedPeersCount != 1)
{
Thread.Sleep(15);
client1.PollEvents();
client2.PollEvents();
}

Assert.AreEqual(1, client1.ConnectedPeersCount);
Assert.AreEqual(1, client2.ConnectedPeersCount);
}
#endif

[Test, Timeout(TestTimeout)]
public void ConnectionByIpV4Unsynced()
{
Expand Down
21 changes: 21 additions & 0 deletions LiteNetLib.Tests/ReaderWriterSimpleDataTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using LiteNetLib.Utils;

using NUnit.Framework;
using System;

namespace LiteNetLib.Tests
{
Expand Down Expand Up @@ -59,6 +60,26 @@ public void WriteReadByteArray()
Is.EqualTo(readByteArray).AsCollection);
}

#if NET5_0_OR_GREATER
[Test]
public void WriteReadByteSpan()
{
Span<byte> tempBytes = new byte[] { 1, 2, 4, 8 };
var ndw = new NetDataWriter();
ndw.Put(tempBytes);
Span<byte> anotherTempBytes = new byte[] { 16, byte.MaxValue, byte.MinValue };
ndw.Put(anotherTempBytes);

var ndr = new NetDataReader(ndw.Data);
var readByteArray = new byte[7];
ndr.GetBytes(readByteArray, 7);

Assert.That(
new byte[] { 1, 2, 4, 8, 16, byte.MaxValue, byte.MinValue },
Is.EqualTo(readByteArray).AsCollection);
}
#endif

[Test]
public void WriteReadDouble()
{
Expand Down
22 changes: 20 additions & 2 deletions LiteNetLib/InternalPackets.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Net;
using LiteNetLib.Utils;

Expand Down Expand Up @@ -68,6 +68,24 @@ public static NetPacket Make(NetDataWriter connectData, SocketAddress addressByt
Buffer.BlockCopy(connectData.Data, 0, packet.RawData, HeaderSize + addressBytes.Size, connectData.Length);
return packet;
}

#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1
public static NetPacket Make(ReadOnlySpan<byte> connectData, SocketAddress addressBytes, long connectTime, int localId)
{
//Make initial packet
var packet = new NetPacket(PacketProperty.ConnectRequest, connectData.Length+addressBytes.Size);

//Add data
FastBitConverter.GetBytes(packet.RawData, 1, NetConstants.ProtocolId);
FastBitConverter.GetBytes(packet.RawData, 5, connectTime);
FastBitConverter.GetBytes(packet.RawData, 13, localId);
packet.RawData[HeaderSize - 1] = (byte)addressBytes.Size;
for (int i = 0; i < addressBytes.Size; i++)
packet.RawData[HeaderSize + i] = addressBytes[i];
connectData.CopyTo(packet.RawData.AsSpan(HeaderSize + addressBytes.Size));
return packet;
}
#endif
}

internal sealed class NetConnectAcceptPacket
Expand Down Expand Up @@ -130,4 +148,4 @@ public static NetPacket MakeNetworkChanged(NetPeer peer)
return packet;
}
}
}
}
42 changes: 42 additions & 0 deletions LiteNetLib/NetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,48 @@ public NetPeer Connect(IPEndPoint target, NetDataWriter connectionData)
}
}

#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1
/// <summary>
/// Connect to remote host
/// </summary>
/// <param name="target">Server end point (ip and port)</param>
/// <param name="connectionData">Additional data for remote peer</param>
/// <returns>New NetPeer if new connection, Old NetPeer if already connected, null peer if there is ConnectionRequest awaiting</returns>
/// <exception cref="InvalidOperationException">Manager is not running. Call <see cref="Start()"/></exception>
public NetPeer Connect(IPEndPoint target, ReadOnlySpan<byte> connectionData)
{
if (!_isRunning)
throw new InvalidOperationException("Client is not running");

lock (_requestsDict)
{
if (_requestsDict.ContainsKey(target))
return null;

byte connectionNumber = 0;
if (TryGetPeer(target, out var peer))
{
switch (peer.ConnectionState)
{
//just return already connected peer
case ConnectionState.Connected:
case ConnectionState.Outgoing:
return peer;
}
//else reconnect
connectionNumber = (byte)((peer.ConnectionNum + 1) % NetConstants.MaxConnectionNumber);
RemovePeer(peer, true);
}

//Create reliable connection
//And send connection request
peer = new NetPeer(this, target, GetNextPeerId(), connectionNumber, connectionData);
AddPeer(peer);
return peer;
}
}
#endif

/// <summary>
/// Force closes connection and stop all threads.
/// </summary>
Expand Down
20 changes: 20 additions & 0 deletions LiteNetLib/NetPeer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,26 @@ internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id, byte
NetDebug.Write(NetLogLevel.Trace, $"[CC] ConnectId: {_connectTime}, ConnectNum: {connectNum}");
}

#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1
//"Connect to" constructor
internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id, byte connectNum, ReadOnlySpan<byte> connectData)
: this(netManager, remoteEndPoint, id)
{
_connectTime = DateTime.UtcNow.Ticks;
_connectionState = ConnectionState.Outgoing;
ConnectionNum = connectNum;

//Make initial packet
_connectRequestPacket = NetConnectRequestPacket.Make(connectData, remoteEndPoint.Serialize(), _connectTime, id);
_connectRequestPacket.ConnectionNumber = connectNum;

//Send request
NetManager.SendRaw(_connectRequestPacket, this);

NetDebug.Write(NetLogLevel.Trace, $"[CC] ConnectId: {_connectTime}, ConnectNum: {connectNum}");
}
#endif

//"Accept" incoming constructor
internal NetPeer(NetManager netManager, ConnectionRequest request, int id)
: this(netManager, request.RemoteEndPoint, id)
Expand Down
22 changes: 22 additions & 0 deletions LiteNetLib/Utils/NetDataWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ public static NetDataWriter FromBytes(byte[] bytes, int offset, int length)
return netDataWriter;
}

#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1
/// <summary>
/// Creates NetDataWriter from the given <paramref name="bytes"/>.
/// </summary>
public static NetDataWriter FromBytes(Span<byte> bytes)
{
var netDataWriter = new NetDataWriter(true, bytes.Length);
netDataWriter.Put(bytes);
return netDataWriter;
}
#endif

public static NetDataWriter FromString(string value)
{
var netDataWriter = new NetDataWriter();
Expand Down Expand Up @@ -249,6 +261,16 @@ public void Put(byte[] data)
_position += data.Length;
}

#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1
public void Put(ReadOnlySpan<byte> data)
{
if (_autoResize)
ResizeIfNeed(_position + data.Length);
data.CopyTo(_data.AsSpan(_position));
_position += data.Length;
}
#endif

public void PutSBytesWithLength(sbyte[] data, int offset, ushort length)
{
if (_autoResize)
Expand Down