public AsyncState(AsyncBase server, Socket socket, AsyncOperation operation, IAsyncInterface interface_, object user) { m_server = server; m_socket = socket; m_operation = operation; m_current_write_buffer = null; m_read_buffer = new byte[8192]; m_read_event_args = new SocketAsyncEventArgs(); m_read_event_args.Completed += OnIO; m_read_event_args.UserToken = this; m_read_event_args.SetBuffer(m_read_buffer, 0, m_read_buffer.Length); m_write_event_args = new SocketAsyncEventArgs(); m_write_event_args.Completed += OnIO; m_write_event_args.UserToken = this; m_write_buffers = new Queue <AsyncBuffer>(); Context = new AsyncContext(); Context.State = this; Context.User = user; Context.Interface = interface_; }
internal void Write(AsyncBuffer buffer) { lock (m_write_buffers) { m_write_buffers.Enqueue(buffer); // Save the buffer CheckWrite(); // Perform the logic to check for the next write. NOTE: This stays inside the lock to keep FIFO order. } }
private void CheckWrite() { lock (m_write_buffers) { if (m_current_write_buffer == null) // If no write is in progress { if (m_write_buffers.Count > 0) // There is pending data { m_current_write_buffer = m_write_buffers.Dequeue(); // Get the next buffer m_write_event_args.SetBuffer(m_current_write_buffer.Buffer, m_current_write_buffer.Offset, m_current_write_buffer.Count); // Setup the async write DispatchWrite(); // Begin the write } } } }
private bool ProcessWrite(SocketAsyncEventArgs e) { try { if (e.BytesTransferred <= 0 || e.SocketError != SocketError.Success) // Check for errors { try { Context.Interface.OnDisconnect(Context); } catch (Exception) { } Cleanup(); return(false); } lock (m_write_buffers) { m_current_write_buffer.Offset += e.BytesTransferred; // Update index m_current_write_buffer.Count -= e.BytesTransferred; // Update count if (m_current_write_buffer.Count > 0) // If there is data left to be sent { m_write_event_args.SetBuffer(m_current_write_buffer.Offset, m_current_write_buffer.Count); // Setup the next async write DispatchWrite(); // Begin the next write return(true); // Everything is fine } m_current_write_buffer = null; // Clear out the last write object CheckWrite(); // Perform the logic to check for the next write } } catch (Exception) { Cleanup(); return(false); } return(true); // Everything is fine }