如何让自己的Stream类支持序列化

jiaoshiyao 2017-02-20 11:06:11
public class SocketStream : Stream, IDisposable
{
private bool _isDispose;
private bool _isSocketClose;
private bool _isWork;
private bool _isWrite;
public IMemoryPool Pool { get; }
public IBuffer WriteBuffer { get; }
public IBuffer ReadBuffer { get; }
public Socket Socket { get; }
SocketAsyncEventArgs ReadAsyncArgs = new SocketAsyncEventArgs();

protected void Initial()
{
ReadAsyncArgs.Completed += ReadAsyncArgs_Completed;
ReadAsyncArgs.SetBuffer(ReadBuffer.Buffer, ReadBuffer.Offset, ReadBuffer.Count);
}

public void Work()
{
lock (this)
{
if (_isWork == false)
{
_isWork = true;
if (ReadBuffer.Count > 0)
{
ReadAsyncArgs.SetBuffer(ReadBuffer.Offset, ReadBuffer.Count);
if (!this.Socket.ReceiveAsync(ReadAsyncArgs))
{
throw new SocketException();
}
}
else
{
_isWork = false;
}
}
}
}

private void WriteAsyncArgs_Completed(object sender, SocketAsyncEventArgs e)
{
e.Dispose();
}

private void ReadAsyncArgs_Completed(object sender, SocketAsyncEventArgs e)
{
_isWork = false;
if (e.BytesTransferred > 0)
{
this.ReadBuffer.Offset += e.BytesTransferred;
if (ReadSleep != null)
{
ReadSleep.TrySetResult(true);
}
Work();
}
else
{
_isSocketClose = true;
}
}

public SocketStream(Socket Socket, IBuffer ReadBuffer, IBuffer WriteBuffer)
{
this.WriteBuffer = WriteBuffer;
this.ReadBuffer = ReadBuffer;
this.Socket = Socket;
this.Initial();
}

public SocketStream(Socket Socket, IMemoryPool Pool)
: this(Socket, Pool.Malloc(), Pool.Malloc())
{
}

public override bool CanRead
{
get
{
NetworkStream ms = new NetworkStream(null);
return Socket != null && Socket.Connected;
}
}

public override bool CanSeek
{
get
{
return false;
}
}

public override bool CanWrite
{
get
{
return Socket != null && Socket.Connected;
}
}

public override long Length
{
get
{
throw new NotSupportedException();
}
}

public override long Position
{
get
{
throw new NotSupportedException();
}

set
{
throw new NotSupportedException();
}
}

public override void Flush()
{
lock (this)
{
if (this.WriteBuffer.EffectiveBegin < this.WriteBuffer.Offset)
{
SocketAsyncEventArgs WriteAsyncArgs = new SocketAsyncEventArgs();
WriteAsyncArgs.Completed += WriteAsyncArgs_Completed;
WriteAsyncArgs.SetBuffer(WriteBuffer.Buffer, WriteBuffer.Offset, WriteBuffer.Count);
WriteAsyncArgs.SetBuffer(this.WriteBuffer.EffectiveBegin, this.WriteBuffer.Offset);
this.WriteBuffer.Offset = 0;
if (!this.Socket.SendAsync(WriteAsyncArgs))
{
throw new SocketException();
}
}
}
}

public override int Read(byte[] buffer, int offset, int count)
{
var task = ReadAsync(buffer, offset, count);
task.Wait();
return task.Result;
}
TaskCompletionSource<bool> ReadSleep = null;
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (ReadSleep != null)
{
throw new Exception("不支持多线程操作");
}
ReadSleep = new TaskCompletionSource<bool>();
while (!(this.ReadBuffer.Offset > this.ReadBuffer.EffectiveBegin))
{
await ReadSleep.Task;
}
ReadSleep = null;
int ret = this.ReadBuffer.Read(buffer, offset, count);
if (_isWork == false)
{
Work();
}
return ret;
}

public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}

public override void SetLength(long value)
{
throw new NotSupportedException();
}

public override void Write(byte[] buffer, int offset, int count)
{
this.WriteBuffer.Write(buffer, offset, count);
}
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
Write(buffer, offset, count);
}
public override int ReadByte()
{
byte[] t = new byte[1];
int len = Read(t, 0, 1);
return t[0];
}
public override void WriteByte(byte value)
{
this.WriteBuffer.WriteByte(value);
}

public async Task<int> ReadSpecifiesAsync(byte[] buffer, int offset, int count)
{
int end = offset + count;
while (offset < end )
{
offset += await this.ReadAsync(buffer, offset, end - offset);
}
if(count - (end - offset) != 0)
{
throw new Exception("Socket 无法读取对应数据或者已经取消");
}
return count;
}

public async Task<byte[]> ReadSpecifiesAsync(int count)
{
byte[] date = new byte[16];
int len = await ReadSpecifiesAsync(date, 0, date.Length);
if (len < date.Length)
{
throw new SocketException();
}
return date;
}

public async Task<T> ReadVar<T>()
{
if (typeof(T) == typeof(Int16))
{
return (T)(object)BitConverter.ToInt16(await ReadSpecifiesAsync(16), 0);
}
else if (typeof(T) == typeof(Int32))
{
return (T)(object)BitConverter.ToInt32(await ReadSpecifiesAsync(32), 0);
}
else if (typeof(T) == typeof(Int64))
{
return (T)(object)BitConverter.ToInt64(await ReadSpecifiesAsync(64), 0);
}
else if (typeof(T) == typeof(double))
{
return (T)(object)BitConverter.ToDouble(await ReadSpecifiesAsync(64), 0);
}
else if (typeof(T) == typeof(short))
{
return (T)(object)BitConverter.ToSingle(await ReadSpecifiesAsync(32), 0);
}
else if (typeof(T) == typeof(bool))
{
return (T)(object)BitConverter.ToBoolean(await ReadSpecifiesAsync(1), 0);
}
else if (typeof(T) == typeof(char))
{
return (T)(object)BitConverter.ToChar(await ReadSpecifiesAsync(1), 0);
}
else if (typeof(T) == typeof(UInt16))
{
return (T)(object)BitConverter.ToUInt16(await ReadSpecifiesAsync(16), 0);
}
else if (typeof(T) == typeof(UInt32))
{
return (T)(object)BitConverter.ToInt32(await ReadSpecifiesAsync(16), 0);
}
else if (typeof(T) == typeof(UInt64))
{
return (T)(object)BitConverter.ToInt64(await ReadSpecifiesAsync(16), 0);
}
else
{
return (T)(object)0;
}
}
protected override void Dispose(bool disposing)
{
lock (this)
{
if (_isDispose == false)
{
_isDispose = true;
base.Dispose(disposing);
if (!disposing)
{
if (Pool != null)
{
Pool.Free(this.WriteBuffer);
Pool.Free(this.ReadBuffer);
}
if (ReadAsyncArgs != null)
{
ReadAsyncArgs.SetBuffer(null, 0, 0);
ReadAsyncArgs.Completed -= this.ReadAsyncArgs_Completed;
ReadAsyncArgs.Dispose();
ReadAsyncArgs = null;
}
}
}
else
{
throw new ObjectDisposedException(this.GetType().ToString());
}
}
}
}
...全文
125 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
by_封爱 版主 2017-02-21
  • 打赏
  • 举报
回复
看不懂.. 反正网上有大神写好的SocketAsyncEventArgs 直接拿来用了....
jiaoshiyao 2017-02-20
  • 打赏
  • 举报
回复
TcpListener listen = new TcpListener(IPAddress.Parse("127.0.0.1"), 65512);
            listen.Start();
            var newSocket = listen.AcceptSocket();

            IMemoryPool MemoryPool = new MemoryPool(65535);
            SocketStream ss = new SocketStream(newSocket, MemoryPool);
            ss.Work();
            while (true)
            {
                BinaryFormatter format = new BinaryFormatter();
                string text = (string)format.Deserialize(ss);

                Console.WriteLine("[接受到了数据]" + text);
                format.Serialize(ss, text);
            }
这样写的话,报错说值socket不能为null

110,570

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧