Skip to main content

 路由器设置 > 新闻资讯 >

编程思想和网络协议处理

2014-04-12 23:23 浏览:

最近发生了4件事

1.JAVA编程思想
最近在看《JAVA编程思想》,赐予我思想吧,我要编程,字字珠玑,遍地思想啊!
2.最近在实现一个协议
如何判断一段数据是一个IP数据报,这个问题很简单,但是暴露的却是一个大问题。引发的是更多的思想。
3.OpenSSL的心脏流血
一个数据包的包头长度字段标识的长度并不是数据包的真实长度,关键是你为何凭空信任所谓的对端发来的数据。
4.内存保护
不要指望代码的行为是正常的,关键是保护好你的内存,使用mprotect取消所有的访问权限,当你真的要访问的时候再开放权限,一般可以在SIGSEGV的处理中开放权限。最底层的保护最靠谱!对于所有的计算机处理而言,根本的东西就是内存里面的东西。


首先看一下互联网协议的形成


它不是一蹴而就从无到有的,而是站在了许多巨人和侏儒的肩上。
1.互联网通信协议并非从头开始设计的,完全是在电信网(电话通信网)的基础上设计的;
2.互联网通信协议最初运行于通用计算机(以及少量专有嵌入式设备),设计之初的原则是,协议头尽可能的要小以节省带宽。
3.第2点所示的原则称为吝啬原则,设计之初,CPU资源也是一种稀缺资源,因此协议头不但要小,还要简单,便于解析。
4.在更早的终端年代,行规程负责定义格式而对其进行解释,随后影响了网络协议栈的形成。


然后看一下后来的面向对象思想


对个体的分类以及描述,是一种进入文明社会的象征,动物世界和原始人没有描述,它们只有感官形成的观念,文明社会的人类除了人本身还有描述,比如身份证,档案,特征描写,....有人说这是柏拉图的遗毒,但实际上,我们正是生活在柏拉图的抽象的世界里。

类型的出现,作为一种编程的文明社会的开始,意义非凡,它一改曾经的不在乎类型的观念,曾经,你可以做强制类型转换,但是没人没保证这么转换的正确性,可是在对象的世界里,类型是一个最基本的观念,任何数据都要有一个描述来标示自身,这些描述甚至连字段的名字都包含在内,这样你就可以做反射,内省,序列化,要知道动物和野蛮人是不懂内省的...在对象的世界编程,终于可以回答“我是谁?”的问题了,以前,拿到一个指针,你不知道它是什么类型,现在可以知道了。在C语言中,我们执行以下代码:

struct A *a = ...
b = (struct B*)a;
正确吗?实际上只有一种情况下这么转型才是安全的,取决于struct A的定义:
struct A {
       struct B b;
       ...
};
看出什么了吗?这就是类型!在对象的世界编程,如果有一个变量,你可以用反射机制得到它的类型,得到该类型的所有特征。在非对象的世界,大量的系统崩溃都是因为“不恰当的转型”引发的,所有的代码丝毫没有类型检查机制,所有的东西都在内存里,程序可以任意解释内存里数据的内容,实际上正确的做法是,内容的元数据,内容的类型信息,描述信息等也要和内容保存在一起,正如我们的身份证要随身携带一样,按照严格的做法,如果我不能证明你的身份信息,我甚至都不能证明自己是一个人,之所以人家觉得我起码还是一个人,可能是因为对方觉得我和他长得差不多,但是这种方式是不严格的。

最后看一下协议的处理



对于网络数据包而言,你无法证明该数据包就是一个严格的IP数据包或者就是一个HTTP数据包,当然我不能如此苛刻的对待IP这种已经很完美的协议,幸运的是,由于继承了电信信令协议的简单性特征,我们真的没必要对IP太苛刻,换句话说,我们可以经过很少的检测证明一段数据就是一个IP数据包,因为我们只需要判断不多的几个字段符合IP协议头的格式即可。但是对于应用协议,这种做法就不合适了。

数据通信领域可以分为两个子系统,位于传输层之上的属于内容子系统,而此之下的属于传输子系统,等价的分类是我们熟悉的资源子网和通信子网之间的分类。对于通信子网而言,协议是标准的,因此可以使用电信网的那一套规程,但是现如今人们把那套做法移植到了应用层,这就是滋生BUG的温床。虽然很多应用层协议也是标准化的,但是这种标准化是不能指望的,你不能说它恰好没有出错就说这种方式一定就是合适的。在很早之前的一篇文章中我就说过,应用层协议一定要有一种自解释的机制,应用层协议的目的是信息交换,这就涉及到了编码和对编码的解释,是不是很像对象的序列化和反序列化,这种情况下,能拿到的只有交换数据本身而不能指望其它,指望其它就意味着可能被欺骗,而通信子网的目的并不是信息交换,它只是一种标识机制,不会涉及复杂的解释问题,所以不需要自解释。
      对象的序列化是一种方式,而更为普遍的是XML和ASN.1方式,对于XML而言,除了数据内容之外,还有节点属性,名字等,对于ASN.1而言,任何东西都可以用一种统一的TLV形式编码,包括内容和描述。我们抛开网络协议,只考虑一种情景,给你一段二进制数据,请告诉我它是什么类型。当你实现这个的时候,你是模仿IP的方式还是使用ASN.1的方式呢?
      RMI是一种融合了逻辑处理的数据交换,可能更好?