通信协议,顾名思义就是在网络中终端直接进行通信时所要遵循的规则、要求,如连接到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),则知道这是一个登录信息,再进行其他操作。不会有前两种可能出现的情况,相对安全。所以在以后的文章中我也采用这种协议形式。 照旧选一张图片,不然大段的文字实在让人难以看完。有喜欢车的朋友吗?