当前位置:编程学习 > C#/ASP.NET >>

博客园的C#网络编程(异步传输字符串) - Part.3中定义的通讯协议中的疑惑?

定义这样一个协议:

[length=XXX]:其中xxx是实际发送的字符串长度(注意不是字节数组buffer的长度),那么对于上面的请求,则我们发送的数据为:“[length=25]Welcome to TraceFact.Net!”。而服务端接收字符串之后,首先读取这个“元数据”的内容,然后再根据“元数据”内容来读取实际的数据,它可能有下面这样两种情况:

NOTE:我觉得这里借用“元数据”这个术语还算比较恰当,因为“元数据”就是用来描述数据的数据。

•“[“”]”中括号是完整的,可以读取到length的字节数。然后根据这个数值与后面的字符串长度相比,如果相等,则说明发来了一条完整信息;如果多了,那么说明接收的字节数多了,取出合适的长度,并将剩余的进行缓存;如果少了,说明接收的不够,那么将收到的进行一个缓存,等待下次请求,然后将两条合并。
•“[”“]”中括号本身就不完整,此时读不到length的值,因为中括号里的内容被截断了,那么将读到的数据进行缓存,等待读取下次发送来的数据,然后将两次合并之后再按上面的方式进行处理。

但是,他说这个协议有问题:

使用这种定义协议的方式有它的优点,但缺点也很明显,如果客户知道了这个协议,有意地输入[length=xxx],但是后面的长度却不匹配,此时程序就会出错。可选的解决办法是对“[”和“]”进行编码,当客户端有意输入这两个字符时,我们将它替换成“\[”和“\]”或者别的字符,在读取后再将它还原。


对“[”和“]”进行编码,当客户端有意输入这两个字符时,我们将它替换成“\[”和“\]”或者别的字符,在读取后再将它还原。

进行编码是什么怎么个原理,具体是怎么实现的呢?我搞不明白,都是“[”和“]”,难道可以通过编码就能区分吗?如果能区分,怎么区分呢? --------------------编程问答-------------------- jimmy zhang这篇文章的网址:C#网络编程(异步传输字符串) - Part.3 
http://www.cnblogs.com/JimmyZhang/archive/2008/09/16/1291854.html --------------------编程问答-------------------- 说白了就是对这些“特殊符号”进行转义替换,然后读取的时候再转为原始的情形。最直接的,定义一套替换规则,就可以。 --------------------编程问答-------------------- --------------------编程问答-------------------- 换一句话说,我随便写一行,都可以无歧义地确定其中的[]是特殊字符还是普通字符。 --------------------编程问答-------------------- 客户端输入数据错误,服务器端产生异常是很正常的啊。
客户端有意乱来,你为什么还要正常服务呢?

服务器端 真正需要防的是攻击,比如内存占用,比如非正常对象的反序列化。。。 --------------------编程问答-------------------- 我是不是需要在定制的这个协议中,对[length=XXX]中的“[”和“]”进行特殊编码,大白话就是转换成只有我自己知道的字符,例如:转换成0x0001和0x0003,来分别代替“[”和“]”。这个规则只有我自己知道,实际我是用0x0001和0x0003分别代替“[”和“]”。

如果客户是恶意输入了[length=XXX],但是“[”和“]”没有进行特殊处理,我能根据我知道的规则找到客户输入的“[”和“]”,并对其进行特殊处理。

引用 3 楼 caozhy 的回复:
这很简单,
如果是作为特殊字符,那么[前面没有\
比如
[length=123] 这里[]就是特殊字符
\[length=123\] 这里length就是一般字符
[length=\[123\]]表示length="[123]"
再比如
[length=\\\[123\\\]]表示length="\[123\]",这里外侧的[]是特殊字符,里面的都是转义字符。
--------------------编程问答-------------------- --------------------编程问答-------------------- 大体上明白了转义字符的作用,谢谢斑竹的讲解。

引用 7 楼 caozhy 的回复:
Quote: 引用 6 楼 frustrate2 的回复:

我是不是需要在定制的这个协议中,对[length=XXX]中的“[”和“]”进行特殊编码,大白话就是转换成只有我自己知道的字符,例如:转换成0x0001和0x0003,来分别代替“[”和“]”。这个规则只有我自己知道,实际我是用0x0001和0x0003分别代替“[”和“]”。

如果客户是恶意输入了[length=XXX],但是“[”和“]”没有进行特殊处理,我能根据我知道的规则找到客户输入的“[”和“]”,并对其进行特殊处理。

Quote: 引用 3 楼 caozhy 的回复:

这很简单,
如果是作为特殊字符,那么[前面没有\
比如
[length=123] 这里[]就是特殊字符
\[length=123\] 这里length就是一般字符
[length=\[123\]]表示length="[123]"
再比如
[length=\\\[123\\\]]表示length="\[123\]",这里外侧的[]是特殊字符,里面的都是转义字符。


转义字符没有这样的功能,它并非阻止恶意的输入,而是对合法,但是和保留字冲突的输入作消歧处理。
使得同一行文本只有确定的意思。
我说了,在没有转义语义的情况下,[length=123][length=123]
就有两个意思:
一个是两条length=123
一个是一条length
值是123][length=123
但是有了转义语义
这只能是两条length=123
如果是后者,必须写成[length=123\]\[length=123]

在一套文法系统中,只要用作控制字符(比如界符、关键字、运算符)和用于一般数据的字符有重叠,都必须转义(比如html,C#源程序等等)。在没有转义规则的文法中,控制字符不得作为一般数据字符(比如文件路径中不得出现"\"":")。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,