《Socket异步编程主机端源码.doc》由会员分享,可在线阅读,更多相关《Socket异步编程主机端源码.doc(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Socket异步编程主机端源码一写在前面有计算机技术及接触的人都知道大名鼎鼎的?TCP/IP协议,也知道目前计算机应用中最为“吸金的”网络通讯业务。我们都知道信息推动着社会的步伐,掌握更多优质信息者拥有更宽广的选择空间或更多方案,这就是为什么通讯一直受到重视的原因。 对于一些计算机老手来说,Socket通讯,乃至异步Socket通讯都是一个没有营养的话题,尤其是对于C#这种高度集成且封装的设计语言。但我们暂且不要关心这些思想,在身为菜鸟的岁月里,心沉如水,一丝不苟的完成现在的代码,才是有潜质走好这条路的人。 好了,如果你现在已经打算认真的阅读我的这篇文章,那么关于Socket的问题就来了。二、
2、为什么要选择异步? 这个问题其实不难回答,任何一个选择异步主机端的人想必都明白它不同于“同步”之处。那么就说得更具体点吧:效率因素,用户感受。 要彻底文件搞明白这个问题,你可以尝试做一个WinFrom,在其中定义一个同步Socket主机,只要他能正常跑起来,那当接收到数据时,你应当能直观的感受到,你的Form竟然出现了短暂的停止响应。这是因为你的主线程在维护着一个Socket这样庞大的非托管资源,它对数据的处理势必要占用你这唯一的线程利用率,好比你在看一个小孩子,他淘气的东跑西跑,结果你不得不随时跟着他现在你应该能意识到问题的严重性了吧。用户就是上帝,你不能指望亲爱的上帝给你看孩子,更不能让他
3、们被这孩子牵着鼻子走。而实际工作环境中,用户希望看管的孩子可能还不止一个,那么如何让他们认为自己拥有高效率管理的托管所所长,而不是被一群孩子折腾的脑子发晕的家伙? 我的答案就是“雇保姆”,当然,雇佣费用由我们买单。只要手下有庞大的员工陪着这群顽童,那大老板就可以泡一杯下午茶了。而恰巧,异步源码的设计正好迎合了“多员工管理”的经营理念。好了,先看看代码吧!三、源码namespace SocketServer / / 消息接收委托 / / / public delegate void ReceiveHandler(object sender, AsyncEventArgs e); / / 作用:S
4、ocket异步主机端接口 / 作者:lee / 时间:2009-11-01 / public class Server #region 数据成员 private Socket socket; public event ReceiveHandler receiveEventHandler; private Socket sendBackSocket; #endregion #region 监听 / / 监听所有网络接口上的指定端口 / / 端口号 public void Begin(int port) socket = new Socket(AddressFamily.InterNetwork,
5、 SocketType.Stream, ProtocolType.Tcp); IPEndPoint end = new IPEndPoint(IPAddress.Any, port); socket.Bind(end); /最大监听队列长度为100 socket.Listen(100); /异步监听开始 socket.BeginAccept(new AsyncCallback(Accept), socket); / / 监听指定网络接口Ip的指定端口 / / Ip地址 / 端口号 public void Begin(string ipAddress, int port) socket = ne
6、w Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint end = new IPEndPoint(IPAddress.Parse(ipAddress), port); socket.Bind(end); /最大监听队列长度为100 socket.Listen(100); /异步监听开始 socket.BeginAccept(new AsyncCallback(Accept), socket); #endregion #region 异步接收 / / 异步接收数据 / / void
7、 Accept(IAsyncResult ia) Socket soc = ia.AsyncState as Socket; Socket worker = soc.EndAccept(ia); soc.BeginAccept(new AsyncCallback(Accept), soc); byte buf = new byte1; SocketHelper helper = new SocketHelper(buf, worker); /异步读取数据 worker.BeginReceive(buf, 0, 1, SocketFlags.None, new AsyncCallback(Rec
8、eive), helper); #endregion #region 异步读取 void Receive(IAsyncResult ia) SocketHelper helper = ia.AsyncState as SocketHelper; Socket worker = helper.s; worker.EndReceive(ia); byte buffer = new byteworker.Available + 1; worker.Receive(buffer, 1, buffer.Length - 1, SocketFlags.None); buffer0 = helper.b0;
9、 this.sendBackSocket = worker; /调用事件 this.OnMessageArrival(new AsyncEventArgs(buffer); worker.BeginReceive(helper.b, 0, 1, SocketFlags.None, new AsyncCallback(Receive), helper); #endregion #region 绑定事件 / / 触发消息抵达事件 / / 收到的字节数组 private void OnMessageArrival(AsyncEventArgs e) if (this.receiveEventHand
10、ler != null) this.receiveEventHandler(this, e); #endregion #region 回发消息 public void SendBack(byte buffer) this.sendBackSocket.Send(buffer); #endregion #region 关闭连接 / / 关闭连接 / public void Close() if (this.socket.Connected) this.socket.Close(1); #endregion / / 作用:事件描述信息 / 作者:lee / 时间:2009-11-01 / publ
11、ic class AsyncEventArgs : EventArgs private byte asyncBytes; / / 读取收到的字节数组 / public byte AsynsBytes get return this.asyncBytes; public AsyncEventArgs(byte buffer) this.asyncBytes = buffer; / / 作用:Socket辅助类 / 作者:lee / 时间:2009-11-01 / class SocketHelper public byte b; public Socket s; public SocketHel
12、per(byte buffer, Socket socket) this.b = buffer; this.s = socket; 这部分代码的一部分用到了委托与事件,可能算是唯一的难点了,但委托如同C+中的指针,是必须要啃透的技术点,这对有心人也不算什么。而我在上文提到的“雇佣工人”的思想,代码中也得到了体现。 需要说明的两点是: 1:主机端收到及回发数据均为byte,也就是我们常常见到的字节数组,它是TCP/IP协议最底层数据格式。我将它写进了事件的参数中。之所以这样处理,是考虑到许多硬件设施的通讯便是采用直接发送byte的形式,实际信息常常按照索引项从数组中解析。如果你希望收到strin
13、g,那就需要做一些数据类型转换的处理,好在这并不是难事。 2.我听到一种说法:程序设计最重要的原则,就是想象你的API未来要交给一个手持斧头的偏执狂患者使用,而不巧的是,这位可怕的用户还知道你住在哪儿。这对程序设计者来说实在是一个坏消息,因此从现在开始,把我们的对外接口做的简洁,而且实用吧!下面做一个Demo,示范一下这个程序的调用方法。using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text
14、;using System.Windows.Forms;namespace Test public partial class Form1 : Form SocketServer.Server server; public Form1() InitializeComponent(); server = new SocketServer.Server(); /将下文中的server_receiveEventHandler()方法绑定到事件中 server.receiveEventHandler += new SocketServer.ReceiveHandler(server_receiveEventHandler); / / 当收到客户端的数据时触发此方法 / / / void server_receiveEventHandler(object sender, SocketServer.AsyncEventArgs e) byte message = e.AsynsBytes; /e.AsynsBytes即为收到的字节数组 写到这里就差不多了,由SocketServer.Server类提供对用户的接口,使用时直接调用即可。调用越简洁,用户越能获得更好的操作感。 异步通讯就写到这里,欢迎提出更好的建议及不足!