Пример #1
0
            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 unsafe void Execute()
            {
                var count       = 0;
                var outstanding = Rx.InUse;
                var error       = default(ErrorState);
                var requests    = stackalloc Binding.Baselib_RegisteredNetwork_Request[Rx.Capacity];

                if (outstanding > 0)
                {
                    var pollCount = 0;
                    while (Binding.Baselib_RegisteredNetwork_Socket_UDP_ProcessRecv(Baselib[0].m_Socket, error.NativeErrorStatePtr) == Binding.Baselib_RegisteredNetwork_ProcessStatus.Pending && pollCount++ < k_defaultRxQueueSize)
                    {
                    }

                    var results = stackalloc Binding.Baselib_RegisteredNetwork_CompletionResult[outstanding];

                    // Pop Completed Requests off the CompletionQ
                    count = (int)Binding.Baselib_RegisteredNetwork_Socket_UDP_DequeueRecv(Baselib[0].m_Socket, results, (uint)outstanding, error.NativeErrorStatePtr);
                    if (error.ErrorCode != ErrorCode.Success)
                    {
                        Receiver.ReceiveErrorCode = (int)error.ErrorCode;
                        return;
                    }

                    // Copy and run Append on each Packet.

                    var stream       = Receiver.GetDataStream();
                    var headerLength = UnsafeUtility.SizeOf <UdpCHeader>();
                    var address      = default(NetworkInterfaceEndPoint);

                    var indicies = stackalloc int[count];
                    for (int i = 0; i < count; i++)
                    {
                        if (results[i].status == Binding.Baselib_RegisteredNetwork_CompletionStatus.Failed)
                        {
                            // todo: report error?
                            continue;
                        }
                        var receivedBytes = (int)results[i].bytesTransferred;
                        var index         = (int)results[i].requestUserdata - 1;
                        var packet        = Rx.GetRequestFromHandle(index);

                        indicies[i] = index;
                        outstanding--;

                        // todo: make sure we avoid this copy
                        var payloadLen = receivedBytes - headerLength;

                        int dataStreamSize = Receiver.GetDataStreamSize();
                        if (Receiver.DynamicDataStreamSize())
                        {
                            while (dataStreamSize + payloadLen >= stream.Length)
                            {
                                stream.ResizeUninitialized(stream.Length * 2);
                            }
                        }
                        else if (dataStreamSize + payloadLen > stream.Length)
                        {
                            Receiver.ReceiveErrorCode = 10040;//(int)ErrorCode.OutOfMemory;
                            continue;
                        }

                        UnsafeUtility.MemCpy(
                            (byte *)stream.GetUnsafePtr() + dataStreamSize,
                            (byte *)packet.payload.data + headerLength,
                            payloadLen);

                        var remote = packet.remoteEndpoint.slice;
                        address.dataLength = (int)remote.size;
                        UnsafeUtility.MemCpy(address.data, (void *)remote.data, (int)remote.size);
                        Receiver.ReceiveCount += Receiver.AppendPacket(address, *(UdpCHeader *)packet.payload.data, receivedBytes);
                    }
                    // Reuse the requests after they have been processed.
                    for (int i = 0; i < count; i++)
                    {
                        requests[i] = Rx.GetRequestFromHandle(indicies[i]);
                        requests[i].requestUserdata = (IntPtr)indicies[i] + 1;
                    }
                }

                while (Rx.InUse < Rx.Capacity)
                {
                    int handle = Rx.AcquireHandle();
                    requests[count] = Rx.GetRequestFromHandle(handle);
                    requests[count].requestUserdata = (IntPtr)handle + 1;
                    ++count;
                }
                if (count > 0)
                {
                    count = (int)Binding.Baselib_RegisteredNetwork_Socket_UDP_ScheduleRecv(
                        Baselib[0].m_Socket,
                        requests,
                        (uint)count,
                        error.NativeErrorStatePtr);
                    if (error.ErrorCode != ErrorCode.Success)
                    {
                        Receiver.ReceiveErrorCode = (int)error.ErrorCode;
                    }
                }
            }