您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

166 行
4.9 KiB

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Unity.Collections.LowLevel.Unsafe;
namespace Unity.Networking.Transport
{
public enum NetworkFamily
{
UdpIpv4 = AddressFamily.InterNetwork,
IPC = AddressFamily.Unspecified
}
[StructLayout(LayoutKind.Explicit)]
public unsafe struct NetworkEndPoint
{
internal const int Length = 28;
[FieldOffset(0)] internal fixed byte data[28];
[FieldOffset(0)] internal sa_family_t family;
[FieldOffset(2)] private ushort port;
[FieldOffset(4)] internal int ipc_handle;
[FieldOffset(28)] internal int length;
public ushort Port
{
get { return (ushort) IPAddress.NetworkToHostOrder((short) port); }
set { port = (ushort) IPAddress.HostToNetworkOrder((short) value); }
}
public NetworkFamily Family
{
get => (NetworkFamily) family.sa_family;
#if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS)
set => family.sa_family = (byte) value;
#else
set => family.sa_family = (ushort)value;
#endif
}
public bool IsValid => Family != 0;
public static implicit operator NetworkEndPoint(EndPoint ep)
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
if (!(ep is IPEndPoint))
throw new InvalidOperationException("NetworkEndPoint can only be created from IPEndPoint");
#endif
var endpoint = ep as IPEndPoint;
switch (endpoint.AddressFamily)
{
case AddressFamily.InterNetwork:
{
var sai = new sockaddr_in();
#if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS)
sai.sin_family.sa_family = (byte) AddressFamily.InterNetwork;
sai.sin_family.sa_len = (byte) sizeof(sockaddr_in);
#else
sai.sin_family.sa_family = (ushort) AddressFamily.InterNetwork;
#endif
sai.sin_port = (ushort) IPAddress.HostToNetworkOrder((short) endpoint.Port);
sai.sin_addr.s_addr = (uint) BitConverter.ToInt32(endpoint.Address.GetAddressBytes(), 0);
var len = sizeof(sockaddr_in);
var address = new NetworkEndPoint
{
length = len
};
UnsafeUtility.MemCpy(address.data, sai.data, len);
return address;
}
}
return default(NetworkEndPoint);
}
public string GetIp()
{
var ipAndPort = ToEndPoint(this).ToString();
return ipAndPort.Substring(0, ipAndPort.IndexOf(':'));
}
public static EndPoint ToEndPoint(NetworkEndPoint ep)
{
switch (ep.Family)
{
case NetworkFamily.UdpIpv4:
{
var soi = new sockaddr_in();
UnsafeUtility.MemCpy(soi.data, ep.data, 16);
return new IPEndPoint(new IPAddress(soi.sin_addr.s_addr),
(int) ((ushort) System.Net.IPAddress.NetworkToHostOrder((short) (soi.sin_port))));
}
case NetworkFamily.IPC:
throw new NotImplementedException();
default:
throw new NotImplementedException();
}
}
public static bool operator ==(NetworkEndPoint lhs, NetworkEndPoint rhs)
{
return lhs.Compare(rhs);
}
public static bool operator !=(NetworkEndPoint lhs, NetworkEndPoint rhs)
{
return !lhs.Compare(rhs);
}
public override bool Equals(object other)
{
return this == (NetworkEndPoint) other;
}
public override int GetHashCode()
{
fixed (byte* p = data)
unchecked
{
var result = 0;
for (int i = 0; i < Length; i++)
{
result = (result * 31) ^ (int) (p + 1);
}
return result;
}
}
#if !UNITY_2018_3_OR_NEWER
private int memcmp(void* ptr1, void* ptr2, int size)
{
for (int i = 0; i < size; ++i)
{
if (((byte*) ptr1)[i] != ((byte*) ptr2)[i])
return 1;
}
return 0;
}
#endif
bool Compare(NetworkEndPoint other)
{
if (length != other.length)
return false;
fixed (void* p = this.data)
{
#if UNITY_2018_3_OR_NEWER
if (UnsafeUtility.MemCmp(p, other.data, length) == 0)
#else
if (memcmp(p, other.data, length) == 0)
#endif
return true;
}
return false;
}
}
}