int CreateAndBindSocket(out long socket, network_address address) { socket = -1; int errorcode = 0; int ret = NativeBindings.network_create_and_bind(ref socket, ref address, ref errorcode); if (ret != 0) { return(errorcode); } #if ENABLE_UNITY_COLLECTIONS_CHECKS AllSockets.OpenSockets.Add(socket); #endif if ((ret = NativeBindings.network_set_nonblocking(socket, ref errorcode)) != 0) { return(errorcode); } if ((ret = NativeBindings.network_set_send_buffer_size(socket, ushort.MaxValue, ref errorcode)) != 0) { return(errorcode); } if ((ret = NativeBindings.network_set_receive_buffer_size(socket, ushort.MaxValue, ref errorcode)) != 0) { return(errorcode); } #if (UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN) // Avoid WSAECONNRESET errors when sending to an endpoint which isn't open yet (unclean connect/disconnects) NativeBindings.network_set_connection_reset(socket, 0); #endif return(0); }
unsafe int NativeReceive(ref UdpCHeader header, void *data, int length, ref network_address address) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (length <= 0) { throw new ArgumentException("Can't receive into 0 bytes or less of buffer memory"); } #endif var iov = stackalloc network_iovec[2]; fixed(byte *ptr = header.Data) { iov[0].buf = ptr; iov[0].len = UdpCHeader.Length; iov[1].buf = data; iov[1].len = length; } int errorcode = 0; var result = NativeBindings.network_recvmsg(socket, iov, 2, ref address, ref errorcode); if (result == -1) { if (errorcode == 10035 || errorcode == 35 || errorcode == 11) { return(0); } receiver.ReceiveErrorCode = errorcode; } return(result); }
public unsafe int SendMessage(void *iov, int iov_len, ref network_address address) { if (m_LocalEndPoint[0].family != NetworkFamily.IPC || m_LocalEndPoint[0].port == 0) { m_LocalEndPoint[0] = IPCManager.Instance.CreateEndPoint(); } return(IPCManager.Instance.SendMessageEx(m_LocalEndPoint[0], iov, iov_len, ref address)); }
unsafe int NativeReceive(ref UdpCHeader header, void *data, int length, ref network_address address) { if (length <= 0) { Debug.LogError("Can't receive into 0 bytes or less of buffer memory"); return(0); } var iov = stackalloc network_iovec[2]; fixed(byte *ptr = header.Data) { iov[0].buf = ptr; iov[0].len = UdpCHeader.Length; iov[1].buf = data; iov[1].len = length; } var result = m_NetworkInterface.ReceiveMessage(iov, 2, ref address); if (result == -1) { int err = Marshal.GetLastWin32Error(); if (err == 10035 || err == 35 || err == 11) { return(0); } Debug.LogError(string.Format("error on receive {0}", err)); throw new SocketException(err); } if (result > 0) { DebugLog("NativeReceive Type=" + (UdpCProtocol)header.Type + " HdrLength=" + UdpCHeader.Length + " PayloadSize=" + length + " Result=" + result); string dump = "("; fixed(byte *ptr = header.Data) { for (int i = 0; i < UdpCHeader.Length; ++i) { dump += ptr[i].ToString("X"); } } dump += ") "; for (int i = 0; i < result - UdpCHeader.Length; ++i) { dump += ((byte *)data)[i].ToString("X"); } DebugLog("Dump=" + dump); } return(result); }
int SendPacket(UdpCProtocol type, network_address address) { var header = new UdpCHeader { Type = (byte)type }; unsafe { return(NativeSend(ref header, null, 0, address)); } }
Connection GetConnection(network_address address) { for (int i = 0; i < m_ConnectionList.Length; i++) { if (address.ReallyEquals(m_ConnectionList[i].Address)) { return(m_ConnectionList[i]); } } return(Connection.Null); }
unsafe int NativeSend(ref UdpCHeader header, void *payload, int payloadSize, network_address remote) { var iov = stackalloc network_iovec[2]; int result; fixed(byte *ptr = header.Data) { iov[0].buf = ptr; iov[0].len = UdpCHeader.Length; iov[1].buf = payload; iov[1].len = payloadSize; result = m_NetworkInterface.SendMessage(iov, 2, ref remote); } DebugLog("NativeSend Type=" + (UdpCProtocol)header.Type + " HdrLength=" + UdpCHeader.Length + " PayloadSize=" + payloadSize + " Result=" + result); string dump = "("; fixed(byte *ptr = header.Data) { for (int i = 0; i < UdpCHeader.Length; ++i) { dump += ptr[i].ToString("X"); } } dump += ") "; for (int i = 0; i < payloadSize; ++i) { dump += ((byte *)payload)[i].ToString("X"); } DebugLog("Dump=" + dump); if (result == -1) { int error = Marshal.GetLastWin32Error(); throw new SocketException(error); } return(result); }
public unsafe void Execute() { var address = new network_address { length = network_address.Length }; var header = new UdpCHeader(); var stream = receiver.GetDataStream(); receiver.ReceiveCount = 0; receiver.ReceiveErrorCode = 0; while (true) { int dataStreamSize = receiver.GetDataStreamSize(); if (receiver.DynamicDataStreamSize()) { while (dataStreamSize + NetworkParameterConstants.MTU - UdpCHeader.Length >= stream.Length) { stream.ResizeUninitialized(stream.Length * 2); } } else if (dataStreamSize >= stream.Length) { return; } var result = NativeReceive(ref header, (byte *)stream.GetUnsafePtr() + dataStreamSize, Math.Min(NetworkParameterConstants.MTU - UdpCHeader.Length, stream.Length - dataStreamSize), ref address); if (result <= 0) { return; } var endpoint = default(NetworkInterfaceEndPoint); endpoint.dataLength = UnsafeUtility.SizeOf <network_address>(); UnsafeUtility.MemCpy(endpoint.data, &address, endpoint.dataLength); receiver.ReceiveCount += receiver.AppendPacket(endpoint, header, result); } }
public static unsafe network_address ToNetworkAddress(NetworkEndPoint ep) { switch (ep.family) { case NetworkFamily.UdpIpv4: return(SocketExtension.MarshalIpV4Address(ep.address, ep.port)); case NetworkFamily.IPC: network_address addr = default(network_address); // TODO: Double check this works on ios as well. #if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) addr.family.sa_family = (byte)AddressFamily.Unspecified; #else addr.family.sa_family = (ushort)AddressFamily.Unspecified; #endif addr.ipc_handle = *(int *)ep.address; addr.length = 6; return(addr); default: throw new NotImplementedException(); } }
unsafe int ProcessPackets(BitStream bs) { var address = new network_address(); address.length = sizeof(network_address); var header = new UdpCHeader(); while (true) { if (bs.WriteCapacity <= 0) { return(0); } var sliceOffset = bs.GetBytesWritten(); var result = NativeReceive(ref header, bs.UnsafeDataPtr + sliceOffset, Math.Min(NetworkParameterConstants.MTU, bs.WriteCapacity), ref address); if (result <= 0) { return(result); } switch ((UdpCProtocol)header.Type) { case UdpCProtocol.ConnectionRequest: { if (!Listening) { continue; } Connection c; if ((c = GetConnection(address)) == Connection.Null || c.State == NetworkConnection.State.Destroyed) { int id; if (!m_FreeList.AquireConnectionId(out id)) { SendPacket(UdpCProtocol.ConnectionReject, address); continue; } int ver = m_ConnectionList[id].Version; c = new Connection() { Id = id, Version = ver, State = NetworkConnection.State.Connected, Address = address, Attempts = 1, LastAttempt = Timer.ElapsedMilliseconds }; SetConnection(c); AddConnection(c.Id); } else { c.Attempts++; c.LastAttempt = Timer.ElapsedMilliseconds; SetConnection(c); } SendPacket(UdpCProtocol.ConnectionAccept, new NetworkConnection { m_NetworkId = c.Id, m_NetworkVersion = c.Version }); } break; case UdpCProtocol.ConnectionReject: { // m_EventQ.Enqueue(Id, (int)NetworkEvent.Connect); } break; case UdpCProtocol.ConnectionAccept: { Connection c = GetConnection(address); if (c != Connection.Null) { if (c.State == NetworkConnection.State.Connected) { //DebugLog("Dropping connect request for an already connected endpoint [" + address + "]"); continue; } if (c.State == NetworkConnection.State.Connecting) { c.State = NetworkConnection.State.Connected; UpdateConnection(c); AddConnection(c.Id); } } } break; case UdpCProtocol.Disconnect: { DebugLog("Disconnect packet received from " + address); Connection c = GetConnection(address); if (c != Connection.Null) { RemoveConnection(c); AddDisconnection(c.Id); } } break; case UdpCProtocol.Data: { Connection c = GetConnection(address); if (c == Connection.Null) { continue; } c.LastAttempt = Timer.ElapsedMilliseconds; UpdateConnection(c); if (c.State == NetworkConnection.State.Connecting) { c.State = NetworkConnection.State.Connected; UpdateConnection(c); AddConnection(c.Id); } var length = result - UdpCHeader.Length; bs.IncreaseWritePtr(length); m_EventQueue.PushEvent(new NetworkEvent { connectionId = c.Id, type = NetworkEvent.Type.Data, offset = sliceOffset, size = length }); } break; } } }
public unsafe int ReceiveMessageEx(NetworkEndPoint local, void *iov, int iov_len, ref network_address remote) { var vec = stackalloc network_iovec[iov_len]; int totalLength = 0; NetworkEndPoint from; for (int i = 0; i < iov_len; i++) { int length; int result; vec[i] = UnsafeUtility.ReadArrayElement <network_iovec>(iov, i); if ((result = RecvFrom(local, vec[i].buf, out length, out from)) < 0) { return(result); } Assert.IsTrue(from.family == NetworkFamily.IPC); vec[i].len = length; totalLength += length; // TODO: Double check this works on ios as well. #if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) remote.family.sa_family = (byte)AddressFamily.Unspecified; #else remote.family.sa_family = (ushort)AddressFamily.Unspecified; #endif remote.ipc_handle = *(int *)from.address; remote.length = 6; } return(totalLength); }
public unsafe int SendMessageEx(NetworkEndPoint local, void *iov, int iov_len, ref network_address address) { var vec = stackalloc network_iovec[iov_len]; NetworkEndPoint endpoint; if (!TryGetEndPointByHandle(address.ipc_handle, out endpoint)) { return(-1); } for (int i = 0; i < iov_len; i++) { vec[i] = UnsafeUtility.ReadArrayElement <network_iovec>(iov, i); } int length = 0; for (int i = 0; i < iov_len; i++) { int result; if ((result = SendTo(local, vec[i].buf, vec[i].len, endpoint)) < 0) { return(result); } length += result; } return(length); }
public unsafe int SendMessage(void *iov, int iov_len, ref network_address address) { return(SocketExtension.SendMessageEx(m_SocketHandle, iov, iov_len, ref address)); }
public unsafe int ReceiveMessage(void *iov, int iov_len, ref network_address address) { Assert.IsTrue(m_LocalEndPoint[0].family == NetworkFamily.IPC && m_LocalEndPoint[0].port != 0); return(IPCManager.Instance.ReceiveMessageEx(m_LocalEndPoint[0], iov, iov_len, ref address)); }