internal class MyStream : Stream { #region "constants" public int RECEIVE_BUFFER_SIZE = 4096; public SocketFlags SOCKET_FLAGS = SocketFlags.None; #endregion #region events public delegate void OnReceiveHandler(int count); public event OnReceiveHandler OnReceive; #endregion #region constructor public MyStream(Socket sock) { m_socket = sock; m_recvBuffer = new MemoryStream(); m_sendBuffer = new MemoryStream(); _beginReceive(); } #endregion #region properties public override long Length { get { return m_recvBuffer.Length; } } public override bool CanRead { get { return m_socket.Connected; } } public override bool CanWrite { get { return m_socket.Connected; } } public override bool CanSeek { get { return true; } } public override long Position { get { return 0; } set { Seek(value, SeekOrigin.Begin); } } #endregion #region manipulate-methods public override void SetLength(long value) { lock (m_recvBuffer) m_recvBuffer.SetLength(value); } public override int Read(byte[] buffer, int offset, int count) { lock (m_recvBuffer) { // read data from buffer + remove it m_recvBuffer.Seek(0, SeekOrigin.Begin); // debug int read = m_recvBuffer.Read(buffer, offset, count); _cutBuffer(ref m_recvBuffer, count); return read; } } public override void Write(byte[] buffer, int offset, int count) { lock (m_sendBuffer) { // put data into buffer m_sendBuffer.Seek(0, SeekOrigin.End); // debug m_sendBuffer.Write(buffer, offset, count); } // start asynchronous sending-proccess _beginSend(); } public override long Seek(long offset, SeekOrigin origin) { // remove content < pos long pos; if (origin == SeekOrigin.Begin || origin == SeekOrigin.Current) pos = 0 + offset; else pos = m_recvBuffer.Length - offset; lock(m_recvBuffer) _cutBuffer(ref m_recvBuffer, pos); return 0; } #endregion #region Stream Members public override void Flush() { throw new Exception("The method or operation is not implemented."); } #endregion #region Private Methods private void _beginReceive() { // start asynchronous-receiving-proccess byte[] buffer = new byte[RECEIVE_BUFFER_SIZE]; m_socket.BeginReceive( buffer, 0, RECEIVE_BUFFER_SIZE, SOCKET_FLAGS, new AsyncCallback(_onSockReceive), buffer); } private void _beginSend() { lock(m_sendBuffer) { // clear buffer + send its content byte[] buffer = m_sendBuffer.ToArray(); m_sendBuffer.SetLength(0); m_socket.BeginSend( buffer, 0, buffer.Length, SOCKET_FLAGS, new AsyncCallback(_onSockSend), null); } } private void _onSockReceive(IAsyncResult ar) { // receive data int rcvd = m_socket.EndReceive(ar); lock (m_recvBuffer) { /*debug*/m_recvBuffer.Seek(0, SeekOrigin.End); m_recvBuffer.Write((byte[]) ar.AsyncState, 0, rcvd); } // throw OnReceive event OnReceive(rcvd); // continue receiving.. _beginReceive(); } private void _onSockSend(IAsyncResult ar) { // finish asynchronous-sending-proccess m_socket.EndSend(ar); } private static void _cutBuffer(ref MemoryStream buffer, long pos) { // cut whole content < pos int newSize = (int)(buffer.Length - pos); byte[] temp = new byte[newSize]; buffer.Seek(pos, SeekOrigin.Begin); buffer.Read(temp, 0, newSize); buffer.SetLength(newSize); buffer.Seek(0, SeekOrigin.Begin); buffer.Write(temp, 0, newSize); } #endregion #region Private Members private Socket m_socket; private MemoryStream m_recvBuffer; private MemoryStream m_sendBuffer; #endregion }