static internal unsafe int SendMessageEx(NativeQueue <IPCQueuedMessage> .Concurrent 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);
        }
        public unsafe int ReceiveMessageEx(NetworkInterfaceEndPoint local, network_iovec *iov, int iov_len, ref NetworkInterfaceEndPoint remote)
        {
            IPCData data;

            if (!m_IPCQueue.Peek(*(int *)local.data, out data))
            {
                return(0);
            }
            GetEndPointByHandle(data.from, out remote);

            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(*(int *)local.data, out data);

            return(totalLength);
        }
        public unsafe int SendMessage(network_iovec *iov, int iov_len, ref NetworkEndPoint address)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (m_LocalEndPoint[0].Family != NetworkFamily.IPC || m_LocalEndPoint[0].nbo_port == 0)
            {
                throw new InvalidOperationException();
            }
#endif
            return(IPCManager.SendMessageEx(m_ConcurrentIPCQueue, m_LocalEndPoint[0], iov, iov_len, ref address));
        }
        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);
        }
        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));
        }