/// <summary> /// The receive data method call. /// </summary> /// <param name="data">The data received from the client.</param> private void Receive(byte[] data) { // Make sure data has arrived. if (data != null && data.Length > 0) { // Write to the request stream. _requestStream.WriteToStream(data, 0, data.Length); // Make sure the context exists. if (_context != null) { // If the data available handler has been set // then send a trigger indicating that // data is available. if (_context.OnReceivedHandler != null) { // If not in async mode. if (!_context.IsAsyncMode) { // Received the request from the client. // Send the message context. Receiver(); } } } } }
/// <summary> /// The receive data method call. /// </summary> /// <param name="data">The data received from the client.</param> protected override void Receive(byte[] data) { // Make sure only one thread at a time is adding to the buffer. lock (_lockReceiver) { // Make sure data has arrived. if (data.Length > 0) { // If the upper capacity of the buffer // has been reached then stop writting // until the request buffer gets to the // lower capacity threshold. if (_requestBuffer.IsUpperCapacityPercentage()) { // Create the tasks. Task[] tasks = new Task[1]; Interlocked.Exchange(ref _exitWaitReceiveIndicator, 0); try { // Write to the request stream task. Task readFromStream = Task.Factory.StartNew(() => { // Create a new spin wait. SpinWait sw = new SpinWait(); // Action to perform. while (Interlocked.CompareExchange(ref _exitWaitReceiveIndicator, 0, 1) == 0) { // The NextSpinWillYield property returns true if // calling sw.SpinOnce() will result in yielding the // processor instead of simply spinning. if (sw.NextSpinWillYield) { // If the buffer is below the lower capacity // threshold then exist the spin wait. if (!_requestBuffer.IsLowerCapacityPercentage()) { Interlocked.Exchange(ref _exitWaitReceiveIndicator, 1); } } // Performs a single spin. sw.SpinOnce(); } }); // Assign the listener task. tasks[0] = readFromStream; // Wait for all tasks to complete. Task.WaitAll(tasks); } catch { } // For each task. foreach (Task item in tasks) { try { // Release the resources. item.Dispose(); } catch { } } tasks = null; } // Write to the request stream. _requestStream.WriteToStream(data, 0, data.Length); } } // Make sure data has arrived. if (data.Length > 0) { // Make sure the context exists. if (_context != null) { // If not in async mode. if (!_context.IsAsyncMode) { // Allow an active context. if (Interlocked.CompareExchange(ref _isContextActive, 1, 0) == 0) { // Set the active context indicator to true // no other context can start. Interlocked.Exchange(ref _isContextActive, 1); // Received the request from the client. // Send the message context. Receiver(); } } else { // If the data available handler has been set // then send a trigger indicating that // data is available. if (_context.ReceivedAsyncMode != null) { // Allow an active context. if (Interlocked.CompareExchange(ref _isAsyncModeActive, 1, 0) == 0) { // Set the active context indicator to true // no other context can start. Interlocked.Exchange(ref _isAsyncModeActive, 1); // Received the request from the client. // Send the message context. AsyncModeReceiver(); } } } } } }
/// <summary> /// Data received asynchronus result method, all client commands /// are processed through this asynchronus result method. /// </summary> /// <param name="ar">The current asynchronus result.</param> internal void DataReceiver(IAsyncResult ar) { try { // Clear the last error. ClearLastError(); // Lock the socket receive process. lock (ServerRef.LockingSocket) { // Get the data from the client endpoint. _dataReceiverBytesRead = _socket.EndReceiveFrom(ar, ref RemoteClient); } // Send a Received command to the server // indicating that the client has data. if (OnCommandSend != null) { OnCommandSend(this, "RECEIVED"); } // Make sure only one thread at a time is adding to the buffer. lock (_lockReceiver) { // Make sure data has arrived. if (_dataReceiverBytesRead > 0) { // If the upper capacity of the buffer // has been reached then stop writting // until the request buffer gets to the // lower capacity threshold. if (_requestBuffer.IsUpperCapacityPercentage()) { // Create the tasks. Task[] tasks = new Task[1]; Interlocked.Exchange(ref _exitWaitReceiveIndicator, 0); try { // Write to the request stream task. Task readFromStream = Task.Factory.StartNew(() => { // Create a new spin wait. SpinWait sw = new SpinWait(); // Action to perform. while (Interlocked.CompareExchange(ref _exitWaitReceiveIndicator, 0, 1) == 0) { // The NextSpinWillYield property returns true if // calling sw.SpinOnce() will result in yielding the // processor instead of simply spinning. if (sw.NextSpinWillYield) { // If the buffer is below the lower capacity // threshold then exist the spin wait. if (!_requestBuffer.IsLowerCapacityPercentage()) { Interlocked.Exchange(ref _exitWaitReceiveIndicator, 1); } } // Performs a single spin. sw.SpinOnce(); } }); // Assign the listener task. tasks[0] = readFromStream; // Wait for all tasks to complete. Task.WaitAll(tasks); } catch { } // For each task. foreach (Task item in tasks) { try { // Release the resources. item.Dispose(); } catch { } } tasks = null; } // Write to the request stream. _requestStream.WriteToStream(_readBuffer, 0, _dataReceiverBytesRead); // Set the timeout on first receive. SetTimeOut(); if (_context != null) { // Assign the new client IP endpoint. _context.RemoteEndPoint = GetClientIPEndPoint(); } } } // Make sure data has arrived. if (_dataReceiverBytesRead > 0) { // Make sure the context exists. if (_context != null) { // If not in async mode. if (!_context.IsAsyncMode) { // Allow an active context. if (Interlocked.CompareExchange(ref _isContextActive, 1, 0) == 0) { // Set the active context indicator to true // no other context can start. Interlocked.Exchange(ref _isContextActive, 1); // Received the request from the client. // Send the message context. Receiver(); } } else { // If the data available handler has been set // then send a trigger indicating that // data is available. if (_context.ReceivedAsyncMode != null) { // Allow an active context. if (Interlocked.CompareExchange(ref _isAsyncModeActive, 1, 0) == 0) { // Set the active context indicator to true // no other context can start. Interlocked.Exchange(ref _isAsyncModeActive, 1); // Received the request from the client. // Send the message context. AsyncModeReceiver(); } } } } } } catch (Exception ex) { SetLastError(ex); } }