首页 > 代码库 > GJM : Socket TCP 通信连接(二)
GJM : Socket TCP 通信连接(二)
上一篇中,我们编写了客户端功能。
这一篇将讲解ISocketHandler的实现。
再来回顾一下ISocketHandler接口。
public interface ISocketHandler { /// <summary> /// 开始接收 /// </summary> /// <param name="stream">Socket网络流</param> /// <param name="callback">回调函数</param> /// <param name="state">自定义状态</param> /// <returns>异步结果</returns> IAsyncResult BeginReceive(Stream stream, AsyncCallback callback, object state); /// <summary> /// 结束接收 /// </summary> /// <param name="asyncResult">异步结果</param> /// <returns>接收到的数据</returns> byte[] EndReceive(IAsyncResult asyncResult); /// <summary> /// 开始发送 /// </summary> /// <param name="data">要发送的数据</param> /// <param name="offset">数据偏移</param> /// <param name="count">发送长度</param> /// <param name="stream">Socket网络流</param> /// <param name="callback">回调函数</param> /// <param name="state">自定义状态</param> /// <returns>异步结果</returns> IAsyncResult BeginSend(byte[] data, int offset, int count, Stream stream, AsyncCallback callback, object state); /// <summary> /// 结束发送 /// </summary> /// <param name="asyncResult">异步结果</param> /// <returns>发送是否成功</returns> bool EndSend(IAsyncResult asyncResult); }
做一个类SocketHandler继承ISocketHandler接口
/// <summary> /// Socket处理程序 /// </summary> public class SocketHandler : ISocketHandler { /// <summary> /// 开始接收 /// </summary> /// <param name="stream">Socket网络流</param> /// <param name="callback">回调函数</param> /// <param name="state">自定义状态</param> /// <returns>异步结果</returns> public IAsyncResult BeginReceive(Stream stream, AsyncCallback callback, object state) { } /// <summary> /// 结束接收 /// </summary> /// <param name="asyncResult">异步结果</param> /// <returns>接收到的数据</returns> public byte[] EndReceive(IAsyncResult asyncResult) { } /// <summary> /// 开始发送 /// </summary> /// <param name="data">要发送的数据</param> /// <param name="offset">数据偏移</param> /// <param name="count">发送长度</param> /// <param name="stream">Socket网络流</param> /// <param name="callback">回调函数</param> /// <param name="state">自定义状态</param> /// <returns>异步结果</returns> public IAsyncResult BeginSend(byte[] data, int offset, int count, Stream stream, AsyncCallback callback, object state) { } /// <summary> /// 结束发送 /// </summary> /// <param name="asyncResult">异步结果</param> /// <returns>发送是否成功</returns> public bool EndSend(IAsyncResult asyncResult) { } }
增加两个属性与构造函数。
//异步处理关系集合 private Dictionary<IAsyncResult, SocketHandlerState> StateSet; //发送队列 private List<SocketHandlerState> SendQueue; /// <summary> /// 实例化Socket处理程序 /// </summary> public SocketHandler() { StateSet = new Dictionary<IAsyncResult, SocketHandlerState>(); SendQueue = new List<SocketHandlerState>(); }
StateSet可以保存我们的异步调用结果等数据
SendQueue用来做一个发送队列
接下来我们从发送数据开始。
由于需要用到Stream的异步方法,我们需要定义一个State类。
internal class SocketHandlerState { /// <summary> /// 数据 /// </summary> public byte[] Data { get; set; } /// <summary> /// 异步结果 /// </summary> public IAsyncResult AsyncResult { get; set; } /// <summary> /// Socket网络流 /// </summary> public Stream Stream { get; set; } /// <summary> /// 异步回调函数 /// </summary> public AsyncCallback AsyncCallBack { get; set; } /// <summary> /// 是否完成 /// </summary> public bool Completed { get; set; } /// <summary> /// 数据长度 /// </summary> public int DataLength { get; set; } }
因为我们需要返回IAsyncResult,所以我们继承该接口做一个SocketHandlerState类。
/// <summary> /// Socket异步操作状态 /// </summary> public class SocketAsyncResult : IAsyncResult { /// <summary> /// 实例化Socket异步操作状态 /// </summary> /// <param name="state"></param> public SocketAsyncResult(object state) { AsyncState = state; AsyncWaitHandle = new AutoResetEvent(false); } /// <summary> /// 获取用户定义的对象,它限定或包含关于异步操作的信息。 /// </summary> public object AsyncState { get; private set; } /// <summary> /// 获取用于等待异步操作完成的 System.Threading.WaitHandle。 /// </summary> public WaitHandle AsyncWaitHandle { get; private set; } /// <summary> /// 获取一个值,该值指示异步操作是否同步完成。 /// </summary> public bool CompletedSynchronously { get { return false; } } /// <summary> /// 获取一个值,该值指示异步操作是否已完成。 /// </summary> public bool IsCompleted { get; internal set; } }
然后开始编写发送数据相关函数。
这里我将发送数据的大小限制为最大65535。
只需发送长度为2的头信息即可把数据长度发送到对方。
/// <summary> /// 开始发送 /// </summary> /// <param name="data">要发送的数据</param> /// <param name="offset">数据偏移</param> /// <param name="count">发送长度</param> /// <param name="stream">Socket网络流</param> /// <param name="callback">回调函数</param> /// <param name="state">自定义状态</param> /// <returns>异步结果</returns> public IAsyncResult BeginSend(byte[] data, int offset, int count, Stream stream, AsyncCallback callback, object state) { //data不能为null if (data =http://www.mamicode.com/= null)"data"); //offset不能小于0和超过data长度 if (offset > data.Length || offset < 0) throw new ArgumentOutOfRangeException("offset"); //count不能大于65535 if (count <= 0 || count > data.Length - offset || count > ushort.MaxValue) throw new ArgumentOutOfRangeException("count"); //stream不能为null if (stream == null) throw new ArgumentNullException("stream"); //回调函数不能为null if (callback == null) throw new ArgumentNullException("callback"); //stream异常 if (!stream.CanWrite) throw new ArgumentException("stream不支持写入。"); SocketAsyncResult result = new SocketAsyncResult(state); //初始化SocketHandlerState SocketHandlerState shs = new SocketHandlerState(); shs.Data = http://www.mamicode.com/data;"asyncResult">异步结果</param> /// <returns>发送是否成功</returns> public bool EndSend(IAsyncResult asyncResult) { //判断异步操作状态是否属于当前处理程序 if (!StateSet.ContainsKey(asyncResult)) throw new ArgumentException("无法识别的asyncResult。"); SocketHandlerState state = StateSet[asyncResult]; lock (StateSet) StateSet.Remove(asyncResult); return state.Completed; }
接下来是接收数据的相关方法。
/// <summary> /// 开始接收 /// </summary> /// <param name="stream">Socket网络流</param> /// <param name="callback">回调函数</param> /// <param name="state">自定义状态</param> /// <returns>异步结果</returns> public IAsyncResult BeginReceive(Stream stream, AsyncCallback callback, object state) { //stream不能为null if (stream == null) throw new ArgumentNullException("stream"); //回调函数不能为null if (callback == null) throw new ArgumentNullException("callback"); //stream异常 if (!stream.CanRead) throw new ArgumentException("stream不支持读取。"); SocketAsyncResult result = new SocketAsyncResult(state); //初始化SocketHandlerState SocketHandlerState shs = new SocketHandlerState(); shs.Data = http://www.mamicode.com/new byte[2];"asyncResult">异步结果</param> /// <returns>接收到的数据</returns> public byte[] EndReceive(IAsyncResult asyncResult) { //判断异步操作状态是否属于当前处理程序 if (!StateSet.ContainsKey(asyncResult)) throw new ArgumentException("无法识别的asyncResult。"); SocketHandlerState state = StateSet[asyncResult]; lock (StateSet) StateSet.Remove(asyncResult); return state.Data; }
至此,SocketHandler的功能已经实现。
下一篇将为大家讲解服务器端的实现。
GJM : Socket TCP 通信连接(二)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。