通信协议,顾名思义就是在网络中终端直接进行通信时所要遵循的规则、要求,如连接到Internet有TCP/IP协议,在局域网中有IPX/SPX协议。在上一篇介绍了Socket通信方式,无论TCP还是UDP,都必须是一端先等待消息,接收后再回发消息,接收方必须要知道接收到的消息所代表的意义和具体内容,比如登录消息,聊天消息,登出消息等等。那就有了如何识别消息的要求,也就是协议。

     自己编写的程序,就可以自定义协议。在这里也介绍几种常用自定义协议。

     最简单的协议当然就是定义一个符号或是字符串为关键字,再与所要发送的内容组合成一个字符串,接收方接收到后也按照这个协议来分解字符串。比如:字符串"login“表示这是一个登录消息,登录内容是用户名和密码,那这个协议的内容可以写成:"login|username|password",客户端将这个协议发送出去,服务器接收到后,将得到的字符串分解,第一个子字符串是"login"则知道这是一个登录消息,便会去将后两个子字符串就行处理。当然这样的协议很混乱,很容易出错,当消息内容本身就包含连接符,分解时就会出错,比如,客户端用户名是user|name,那协议就变成了"login|user|name|password",服务器分解的内容也就错了。

     再有的方法是利用固定的格式,如xml的形式,定义出一个节点,比如<name username="username" password="password" >login</name>,将这样协议发送出去,就不会有上一种混乱的情况,服务器在得到信息后先取得节点的InnerText,如"login",知道这是一个登录消息,然后在去取相应的属性就行操作。那这种协议是不是就很好呢,它也会有一定的麻烦,比如如果接收方所接收到的消息不完整,不能转成一个完整的xml节点形式,便会出错。也比较容易被一些不法软件截获信息,很容易分析出通信内容。

     相对以上两种协议,还有一种方式就是将每种通信都定义成自己的类别对象,并序列化转成二进制数组再发送。接收方则将二进制数组反序列化成类别,就可得到相应的信息。要想序列化,则要用到BinaryFormatter,而且在所要序列化的类名前加上[Serializable]。如:
     [Serializable]
     public class Login
     {
          private string username;

          private string password;

          public Login(string username, string password)
          {
               this.username= username;

               this.password = password;

          }
          public string UserName
          {

               get { return username; }

          }

          public string Password
          {

               get { return password; }

          }

     }
     这样接收方在接到消息后反序列化,再判断其类别,比如typeof(Login),则知道这是一个登录信息,再进行其他操作。不会有前两种可能出现的情况,相对安全。所以在以后的文章中我也采用这种协议形式。

     照旧选一张图片,不然大段的文字实在让人难以看完。有喜欢车的朋友吗?
     

posted on 2009-01-03 20:38  Jason Yao  阅读(1258)  评论(0编辑  收藏  举报