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; } } }