rendered paste body 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
}