Пример #1
0
        public int Bind(NetworkEndPoint endpoint)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (endpoint.Family != NetworkFamily.IPC || endpoint.nbo_port == 0)
            {
                throw new InvalidOperationException();
            }
#endif
            IPCManager.Instance.ReleaseEndPoint(m_LocalEndPoint[0]);
            m_LocalEndPoint[0] = endpoint;
            return(0);
        }
Пример #2
0
        private void Close()
        {
            if (m_SocketHandle < 0)
            {
                return;
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AllSockets.OpenSockets.Remove(m_SocketHandle);
#endif
            int errorcode = 0;
            NativeBindings.network_close(ref m_SocketHandle, ref errorcode);
            m_RemoteEndPoint = default(NetworkEndPoint);
            m_SocketHandle   = -1;
        }
Пример #3
0
        public unsafe int ReceiveMessageEx(NetworkEndPoint local, network_iovec *iov, int iov_len, ref NetworkEndPoint remote)
        {
            IPCData data;

            if (!m_IPCQueue.Peek(local.ipc_handle, out data))
            {
                return(0);
            }
            NetworkEndPoint endpoint;

            if (!TryGetEndPointByHandle(data.from, out endpoint))
            {
                return(-1);
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (endpoint.Family != NetworkFamily.IPC)
            {
                throw new InvalidDataException("An incorrect message was pushed to the IPC message queue");
            }
#endif

#if (UNITY_EDITOR_OSX || ((UNITY_STANDALONE_OSX || UNITY_IOS) && !UNITY_EDITOR))
            remote.family.sa_family = (byte)NetworkFamily.IPC;
#else
            remote.family.sa_family = (ushort)NetworkFamily.IPC;
#endif
            remote.ipc_handle = endpoint.ipc_handle;
            remote.nbo_port   = endpoint.nbo_port;
            remote.length     = 6;

            int totalLength = 0;
            for (int i = 0; i < iov_len; i++)
            {
                var curLength = Math.Min(iov[i].len, data.length - totalLength);
                UnsafeUtility.MemCpy(iov[i].buf, data.data + totalLength, curLength);
                totalLength += curLength;
                iov[i].len   = curLength;
            }

            if (totalLength < data.length)
            {
                return(-1);
            }
            m_IPCQueue.Dequeue(local.ipc_handle, out data);

            return(totalLength);
        }
Пример #4
0
        public unsafe bool TryGetEndPointByHandle(int handle, out NetworkEndPoint endpoint)
        {
            endpoint = default(NetworkEndPoint);
            if (handle >= m_IPCEndPoints.Length)
            {
                return(false);
            }

            var temp = new NetworkEndPoint();

            temp.Family     = NetworkFamily.IPC;
            temp.ipc_handle = handle;

            temp.nbo_port   = m_IPCEndPoints[handle];
            endpoint        = temp;
            endpoint.length = 6;
            return(true);
        }
Пример #5
0
        public unsafe void ReleaseEndPoint(NetworkEndPoint endpoint)
        {
            ManagerAccessHandle.Complete();
            if (endpoint.Family == NetworkFamily.IPC)
            {
                int handle = endpoint.ipc_handle;
                m_IPCQueue.Clear(handle);
                // Bump the version of the endpoint
                ushort version = m_IPCEndPoints[handle];
                ++version;
                if (version == 0)
                {
                    version = 1;
                }
                m_IPCEndPoints[handle] = version;

                m_FreeList.Enqueue(handle);
            }
        }
Пример #6
0
        /// <summary>
        /// Create a NetworkEndPoint for IPC. If the EndPoint is passed to Bind the driver will assume ownership,
        /// otherwise the EndPoint must be destroyed by calling ReleaseEndPoint.
        /// </summary>
        public unsafe NetworkEndPoint CreateEndPoint(string name = null)
        {
            ManagerAccessHandle.Complete();
            int id;

            if (!m_FreeList.TryDequeue(out id))
            {
                id = m_IPCEndPoints.Length;
                m_IPCEndPoints.Add(1);
            }

            var endpoint = new NetworkEndPoint
            {
                Family     = NetworkFamily.IPC,
                ipc_handle = id,
                length     = 6,
                nbo_port   = m_IPCEndPoints[id]
            };

            return(endpoint);
        }
Пример #7
0
            public unsafe void Execute()
            {
                var address = new NetworkEndPoint {
                    length = sizeof(NetworkEndPoint)
                };
                var header = new UdpCHeader();
                var stream = receiver.GetDataStream();

                receiver.ReceiveCount     = 0;
                receiver.ReceiveErrorCode = 0;

                while (true)
                {
                    if (receiver.DynamicDataStreamSize())
                    {
                        while (stream.Length + NetworkParameterConstants.MTU >= stream.Capacity)
                        {
                            stream.Capacity *= 2;
                        }
                    }
                    else if (stream.Length >= stream.Capacity)
                    {
                        return;
                    }
                    var sliceOffset = stream.Length;
                    var result      = NativeReceive(ref header, stream.GetUnsafePtr() + sliceOffset,
                                                    Math.Min(NetworkParameterConstants.MTU, stream.Capacity - stream.Length), ref address);
                    if (result <= 0)
                    {
                        // FIXME: handle error
                        if (result < 0)
                        {
                            receiver.ReceiveErrorCode = 10040;
                        }
                        return;
                    }

                    receiver.ReceiveCount += receiver.AppendPacket(address, header, result);
                }
            }
Пример #8
0
        int CreateAndBindSocket(out long socket, NetworkEndPoint 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
            NativeBindings.network_set_nonblocking(socket);
            NativeBindings.network_set_send_buffer_size(socket, ushort.MaxValue);
            NativeBindings.network_set_receive_buffer_size(socket, ushort.MaxValue);
#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);
        }
Пример #9
0
        public int Bind(NetworkEndPoint endpoint)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (endpoint.Family != NetworkFamily.UdpIpv4)
            {
                throw new InvalidOperationException();
            }
#endif

            long newSocket;
            int  ret = CreateAndBindSocket(out newSocket, endpoint);
            if (ret != 0)
            {
                return(ret);
            }
            Close();

            m_RemoteEndPoint = endpoint;
            m_SocketHandle   = newSocket;

            return(0);
        }
Пример #10
0
        public unsafe int SendMessage(network_iovec *iov, int iov_len, ref NetworkEndPoint address)
        {
            int errorcode = 0;

            return(NativeBindings.network_sendmsg(m_SocketHandle, iov, iov_len, ref address, ref errorcode));
        }
Пример #11
0
        static internal unsafe int SendMessageEx(NativeQueue <IPCQueuedMessage> .ParallelWriter queue, NetworkEndPoint local,
                                                 network_iovec *iov, int iov_len, ref NetworkEndPoint address)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (address.Family != NetworkFamily.IPC || local.Family != NetworkFamily.IPC ||
                address.nbo_port == 0 || local.nbo_port == 0)
            {
                throw new InvalidOperationException("Sending data over IPC requires both local and remote EndPoint to be valid IPC EndPoints");
            }
#endif

            var data = new IPCData();
            data.from   = local.ipc_handle;
            data.length = 0;

            for (int i = 0; i < iov_len; i++)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (data.length + iov[i].len >= NetworkParameterConstants.MTU)
                {
                    throw new ArgumentOutOfRangeException("Cannot send more data than an MTU");
                }
#endif
                UnsafeUtility.MemCpy(data.data + data.length, iov[i].buf, iov[i].len);
                data.length += iov[i].len;
            }
            queue.Enqueue(new IPCQueuedMessage {
                dest = address.ipc_handle, data = data
            });
            return(data.length);
        }
Пример #12
0
        public unsafe int PeekNext(NetworkEndPoint local, void *slice, out int length, out NetworkEndPoint from)
        {
            ManagerAccessHandle.Complete();
            IPCData data;

            from   = default(NetworkEndPoint);
            length = 0;

            if (m_IPCQueue.Peek(local.ipc_handle, out data))
            {
                ushort version = m_IPCEndPoints[data.from];

                UnsafeUtility.MemCpy(slice, data.data, data.length);

                length = data.length;
            }

            NetworkEndPoint endpoint;

            if (!TryGetEndPointByHandle(data.from, out endpoint))
            {
                return(-1);
            }
            from = endpoint;

            return(length);
        }