Socket网络编程学习笔记(5)发送和接收实体类数据.doc_第1页
Socket网络编程学习笔记(5)发送和接收实体类数据.doc_第2页
Socket网络编程学习笔记(5)发送和接收实体类数据.doc_第3页
Socket网络编程学习笔记(5)发送和接收实体类数据.doc_第4页
Socket网络编程学习笔记(5)发送和接收实体类数据.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Socket网络编程学习笔记(5):发送和接收实体类数据 在前面讲述的篇幅中,发送的都是文本信息,我们只要通过Encoding中的几个方法把文本转化成二进制数组就可以利用Socket来传输了,这对于一些基本的信息传输能够得到满足,但对于一些复杂的消息交流,则有些“吃力”。我们有时候会把一些信息封闭在一个类中,如果Socket能够传送类对象,那么一些复杂的问题能够通过面向对象来解决了,即方便又安全。大家都知道,要想在网络上传输信息,必须要经过序列化才行,所以在传送类对象时,首选必须对该类对象进行序列化,才能够在网络上进行传输。序列化类对象有三种序列化方法:1、Xml序列化2、Binary序列化3、Soap序列化这几种序列化方法,运用方法相类似,只不过用到的类不一样。在这里也不一一讲述了,有兴趣的朋友可以到网上搜一搜,相信会有不少的收获。这里主要讲一下利用Soap序列化来传送消息。1、首先我们先来建立一个实体类,用来做消息的载体类对象1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;45namespacesbwConsole67Serializable8publicclassSocketData910privateOperateType_operateType;11privateOperateInfo_operateInfo;12privatestring_connString;13privatestring_clientIP;14privatestring_serverIP;1516/*/17/指令传输数据18/19/指令类型20/指令信息21/ASP数据库连接字符串22/子服务器IP23/ASP服务器IP24publicSocketData(OperateTypeoperateType,OperateInfooperateInfo,25stringconnString,stringclientIP,stringserverIP)2627_operateType=operateType;28_operateInfo=operateInfo;29_connString=connString;30_clientIP=clientIP;31_serverIP=serverIP;323334/*/35/指令类型36/37publicOperateTypeOperateType3839getreturn_operateType;40set_operateType=value;4142/*/43/指令信息44/45publicOperateInfoOperateInfo4647getreturn_operateInfo;48set_operateInfo=value;4950/*/51/ASP数据库连接字符串52/53publicstringConnString5455getreturn_connString;56set_connString=value;5758/*/59/子服务器IP60/61publicstringClientIP6263getreturn_clientIP;64set_clientIP=value;6566/*/67/ASP服务器IP68/69publicstringServerIP7071getreturn_serverIP;72set_serverIP=value;73747576/*/77/指令类型78/79publicenumOperateType8081/*/82/网站操作83/84Web=0,85/*/86/升级87/88Upgrade,89/*/90/迁移91/92Transfer939495/*/96/指令信息97/98publicenumOperateInfo99100/*/101/发送102/103Send=0,104/*/105/出错106/107Error,108/*/109/成功110/111Success,112/*/113/重发114/115SendAgain1161171182、发送前先把类对象进行Soap序列化消息发送方法1publicstaticvoidSend(NetworkStreamns,SocketDatasd)23IFormatterformatter=newSoapFormatter();4MemoryStreammem=newMemoryStream();56formatter.Serialize(mem,sd);7bytedata=mem.GetBuffer();8intmemsize=(int)mem.Length;9bytesize=BitConverter.GetBytes(memsize);10ns.Write(size,0,4);11ns.Write(data,0,memsize);12ns.Flush();13mem.Close();14这里利用IFormatter formatter = new SoapFormatter(); MemoryStream mem = new MemoryStream(); formatter.Serialize(mem, sd);对类对象sd进行序列化。在这里还有一个细节值得一提,那就是消息边界问题的处理,这里是利用发送消息的长度方法来实现。代码如下:1intmemsize=(int)mem.Length;2bytesize=BitConverter.GetBytes(memsize);3ns.Write(size,0,4);通过BitConverter.GetBytes()方法可以把数据类型转化为二进制数组,从而可以在网络上传送,所以在接收的时候先接收消息长度,再通过该长度来循环读取完整的消息。3、接收消息接收消息方法1publicstaticSocketDataReceive(NetworkStreamns)23MemoryStreammem=newMemoryStream();4SocketDatasd;5bytedata=newbyte4;6intrevc=ns.Read(data,0,4);7intsize=BitConverter.ToInt32(data,0);8intoffset=0;910if(size0)1112while(size0)1314data=newbyte1024;15revc=ns.Read(data,offset,size);16mem.Write(data,offset,revc);17offset+=revc;18size-=revc;192021IFormatterformatter=newSoapFormatter();22mem.Position=0;23sd=(SocketData)formatter.Deserialize(mem);24mem.Close();2526else2728sd=null;2930returnsd;31通过sd = (SocketData)formatter.Deserialize(mem);还原数据为类对象,就可以对此类对象进行访问了。用Xml序列化或用二进制序列化也是类似,只不过把序列化的方法改一下就可以了,一般来说用二进制序列化得到的数据最小,占用带宽也最小,而用xml和Soap来序列化,都是序列化为Xml格式,所以数据比较大,占用带宽比较大。但用xml或Soap序列化,兼容性高,可以兼容不同系统之间的通信,而二进制不行。可以说各有利弊,可以根据实际情况来选择哪一种序列化。该篇暂时就写到这里了,文字有点乱,请见谅。源码下载:/Files/licongjie/SocketTest4.rarSocket网络编程学习笔记(6):使用线程池提高性能 在前几篇介绍中,不论是服务端的侦听还是客户端的连接都是通过新建一个线程去执行特定功能的。在这种情况下,一量有一个新客户端需要连接,则又得创建新的线程,而当程序创建新线程时,往往需要大量的内部开销,这对程序的性能有一定的影响。在.NET库中提供了一种方法,可以避免一些开销。而在Socket通讯中还有另一种访求那就是异步Socket,我不知道用这种方式的性能如何,在这里且不管这种形式,主要来看一下用线程池解决问题。Windows操作系允许用户维持一池“预先建立的”线程,这个线程池为应用程序中指定的方法提供工作线索。一个线程控制线程池的操作,并用应用程序可以分配附加的线程进行处理。在默认情况下,在线程池中有25个预处理线程,用这种方式可以满足一些小应用。如果要为线程池中的线程注册一个代表,则用下面的格式:ThreadPool.QueueUserWorkItem(new WaitCallback(Counter);其中QueueUserWorkItem是ThreadPool类的一个静态方法;而Counter参数代表运行在线程中的方法,在这要注意的是该Counter方法必须包含一个object 参数,这个在下面的例子中有体现;另外,处Thread对象不一样,代表一旦放置在线程池查询中上,将被处理,不需要其他的方法启动该项工作;当主程序线程退出,所有的线程池线程都将终止,主线程不会等待线程池线程结束。下面我们来看看怎么样运用到我上面讲的例子中去

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论