C#:一个增强的NetworkStream(二)写入
来源:互联网 发布:tcl java待遇怎么样 编辑:程序博客网 时间:2024/05/21 10:02
using System;using System.Net.Sockets;using System.Text;using System.Threading;namespace Splash.Net.Sockets{ /// <summary> /// 异步写状态对象 /// </summary> internal class AsyncWriteStateObject { public ManualResetEvent eventDone; public NetworkStream stream; public Exception exception; } /// <summary> /// 实现TcpClient的异步发送 /// </summary> public partial class NetworkStreamPlus { /// <summary> /// 异步发送 /// </summary> /// <param name="buffer">字节数组</param> /// <param name="offset">起始偏移量</param> /// <param name="size">字节数</param> public void Write(Byte[] buffer, Int32 offset, Int32 size) { // 用户定义对象 AsyncWriteStateObject State = new AsyncWriteStateObject { // 将事件状态设置为非终止状态,导致线程阻止 eventDone = new ManualResetEvent(false), stream = Stream, exception = null, }; Byte[] BytesArray; if (String.IsNullOrEmpty(_secretKey)) { // 在数据前插入长度信息 Int32 Length = size + 4; // 加入4字节长度信息后的总长度 BytesArray = new Byte[Length]; Array.Copy(BitConverter.GetBytes(Length), BytesArray, 4); Array.Copy(buffer, offset, BytesArray, 4, size); } else { // 数据加密 Byte[] Cipher = Encrypt(buffer, offset, size); // 在数据前插入长度信息 Int32 Length = Cipher.Length + 4; BytesArray = new Byte[Length]; Array.Copy(BitConverter.GetBytes(Length), BytesArray, 4); Array.Copy(Cipher, 0, BytesArray, 4, Cipher.Length); } // 写入加长度信息头的数据 Stream.BeginWrite(BytesArray, 0, BytesArray.Length, new AsyncCallback(AsyncWriteCallback), State); // 等待操作完成信号 if (State.eventDone.WaitOne(Stream.WriteTimeout, false)) { // 接收到信号 if (State.exception != null) throw State.exception; } else { // 超时异常 throw new TimeoutException(); } } /// <summary> /// 异步发送 /// </summary> /// <param name="data">字节数组</param> public void Write(Byte[] data) { Write(data, 0, data.Length); } /// <summary> /// 异步发送 /// </summary> /// <param name="command">字符串</param> /// <param name="codePage">代码页</param> /// <remarks> /// 代码页: /// 936:简体中文GB2312 /// 54936:简体中文GB18030 /// 950:繁体中文BIG5 /// 1252:西欧字符CP1252 /// 65001:UTF-8编码 /// </remarks> public void Write(String command, Int32 codePage = 65001) { Write(Encoding.GetEncoding(codePage).GetBytes(command)); } /// <summary> /// 异步写入回调函数 /// </summary> /// <param name="ar">异步操作结果</param> private static void AsyncWriteCallback(IAsyncResult ar) { AsyncWriteStateObject State = ar.AsyncState as AsyncWriteStateObject; try { // 异步写入结束 State.stream.EndWrite(ar); } catch (Exception e) { // 异步连接异常 State.exception = e; } finally { // 将事件状态设置为终止状态,线程继续 State.eventDone.Set(); } } }}