ROS软路由论坛 ROSABC.com 网络方案网络工程交流

 找回密码
 会员注册

QQ登录

只需一步,快速开始

一块积木

2013-12-27 20:32| 发布者: admin| 查看: 709| 评论: 0

摘要:   vs葡萄牙,两脚远射一个头球加上一个乌龙几乎演绎了足球赛场上所有的进球方式。这届队已经收获到了超过他们预想的成绩,而大师菲戈和戈麦斯也用最好的方式为自己的世界杯画上了句号。世界杯快结束了,我四年一次 ...

  vs葡萄牙,两脚远射一个头球加上一个乌龙几乎演绎了足球赛场上所有的进球方式。这届队已经收获到了超过他们预想的成绩,而大师菲戈和戈麦斯也用最好的方式为自己的世界杯画上了句号。世界杯快结束了,我四年一次的业余看球行动也要画上句号,这届世界杯可以说是我看过的最悲情的一届,因为这里面有太多我能认识的球星的极有可能退役,菲戈,齐达内,亨利,欧文,小贝,罗那尔多,卡罗斯,卡福,克雷斯波……甚至是卡恩还有范德萨这些门将,下一届世界杯这些人几乎都不会再上场,我将会看到更多的生面孔。不过就算这些人不在,我也希望世界杯依然能够精彩,带给我四年一次的享受……

  英国如愿拿下了比赛,不过可惜了我昨天睡觉前的最后两个小时。小贝再次证明了自己的右脚绝对是一杆神准的狙击,再次告诉世界:“不要给我禁区右边的任意球机会,要不然,哼哼,你们就等死吧“。英国其他的球员就如同梦游,除了鲁尼还在努力的奔跑,其他的球员就好像拖着十吨铅块在缓慢的移动。中场就好像二流球队一样七零八落(还不是人家冲的),厄瓜多尔真是可惜了。

  荷兰和葡萄牙留下了的纪录,哦,对了,记录中当然还要有牛B的裁判,估计他这辈子也没这么爽过,都没有这么风光的行使过自己的。因为这场比赛,葡萄牙的中场废了,斯特拉里一定在想:“既然不能在杯上刻下自己的名字,那就在耻辱柱上刻,下次我也上去打球员。”

  捷克回家了,今年的捷克就好像旋风一般,来得快去的也快。第一场刮散了美国,但是也废掉了自己的一整条前锋线,第二场窝囊的输给了加纳,第三场更是毫无悬念的被意大利干掉。真是让人遗憾,想想96年的捷克,风卷残云般杀入决赛,要不是比尔霍夫出来拦,那一年捷克就已经登顶了。波波维奇和内德维德已经走完了他们第一次也是最后一次世界杯,剩下的担子就让罗西基们来挑吧。

  上去不由分说就堵了英格兰的一个远射……当即倒地不起……过了好一会儿才起身在站,难道练过了铁功?英格兰直到鲁尼上来以后(虽然没有进球),才打出来一些漂亮的进攻,小贝的漂亮的传中终于再次出现在绿茵场上,英格兰顺利出线咯。

  打不死的韩国队为亚洲赚了点面子,反败为胜也彰显了韩国队的韧劲。日本队因为心态失衡经历的近乎的3分钟快速死亡,留给日本的将是沉重的。沙特的破守门员让他们自己吃尽了苦头。伊朗的马达维基亚和阿里代伊真的可以退役了,他们有资格享受荣耀---这就是亚洲的足球,还有很长的要走。

  西班牙真的很强大,强大的中场使得他们的进球是那么的顺利成章,强大的中场也让舍甫得不到一次射门的机会。4:0还是因为西班牙在下半场把主力换下的情况下才得以截至,但愿这次西班牙军团能走得远一点,舍甫啊,你就安歇吧,乌克兰不能给你支持,虽然你一定会为乌克兰而战。

  要不是阿根廷那场比赛还差强人意,昨天的比赛简直就是垃圾。英格兰居然只是靠一个乌龙球取胜。面对10个人的多巴哥居然0:0收场,还差一点输了。阿根廷的配合真是不错,不过如果不是对手配合不好,那阿根廷也翘了。。。今天晚上再看荷兰,但愿不要打成垃圾。

  PPLive,CCIPTV,TVANTS,居然突然在同一时间都连接不上,难道就不让我看这世界杯了?之时PPStream居然在比赛开始前十分钟连接上了服务器,画质不错,可以慢慢的吃寿司喝啤酒了,哦,对了,还有一些蚬子,呵呵。

  没有罪犯,没有钱财被抢,没有人员死亡,没有指纹,没有,没有任何痕迹,却让纽约的大惊失色---这就是《局内人》描述的一场奇怪的犯罪。发现今年的电影都是以玄疑打天下,局内人如此,幸运数字斯莱文如此,达芬奇密码更不必说。虽然动作没有去年的电影火爆,但是其情节足够引观众的眼球了吧---今年电影比去年好看多了,搞的我到了四点还没睡。

  周末看了两个片,都是放在硬盘里面n久没看的片子,看了一下发现还蛮不错的,一个是《V字仇杀队》,还有一个《幸运数字斯莱文》。而且在那个幸运数字斯莱文里面又看到了布鲁斯・威利斯(这个家伙太爷们了),还有那个长得像曼德拉似的老摩根・弗里曼。心里想着这帮老家伙就算是变成了化石也会继续拍电影的……不过布鲁斯真的有点老了。。。

  单播是说,对特定的主机进行数据传送。例如给某一个主机发送IP数据包。这时候,数据链层给出的数据头里面常具体的目的地址,对于以太网来说,就是网卡的MAC地址(不是FF-FF-FF-FF-FF-FF这样的地址)。现在的具有由功能的主机应该可以将单播数据定向转发,而目的主机的网络接口则可以过滤掉和自己MAC地址不一致的数据。

  是主机针对某一个网络上的所有主机发送数据包。这个网络可能是网络,可能是子网,还可能是所有的子网。如果是网络,例如A类网址的就是netid.255.255.255,如果是子网,则是netid.netid.subnetid.255;如果是所有的子网(B类IP)则是则是netid.netid.255.255。所用的MAC地址FF-FF-FF-FF-FF-FF。网络内所有的主机都会收到这个数据,网卡只要把MAC地址为FF-FF-FF-FF-FF-FF的数据交给内核就可以了。一般说来ARP,或者由协议RIP应该是以的形式播发的。

  可以说是多播的特例,多播就是给一组特定的主机(多播组)发送数据,这样,数据的播发范围会小一些(实际上播发的范围一点也没有变小),多播的MAC地址是最高字节的低位为一,例如01-00-00-00-00-00。多播组的地址是D类IP,是224.0.0.0-239.255.255.255。

  虽然多播比较特殊,但是究其原理,多播的数据还是要通过数据链层进行MAC地址绑定然后进行发送。所以一个以太网卡在绑定了一个多播IP地址之后,必定还要绑定一个多播的MAC地址,才能使得其可以像单播那样工作。这个多播的IP和多播MAC地址有一个对应的算法,在书的p133到p134之间。可以看到这个对应不是一一对应的,主机还是要对多播数据进行过滤。

  个人的看法:和多播的性质是一样的,由器会把数据放到局域网里面,然后网卡对这些数据进行过滤,只拿到自己打算要的数据,比如自己感兴趣的多播数据,自己感兴趣的组播数据。当一个主机运行了一个处理某一个多播IP的进程的时候,这个进程会给网卡绑定一个虚拟的多播mac地址,并做出来一个多播ip。这样,网卡就会让带有这个多播mac地址的数据进来,从而实现通信,而那些没有这些数据的主机就会把这些数据过滤掉,换句话说,多播,是让主机的内核轻松了,而网卡,对不起,您就累点吧。

  一些文章也印证了这种想法,最明显的就是局域网的原理、实现与防范

  可以看到,ping返回了一些随机的ip的结果,这些ip都是与主机在同一子网内的ip。我们可以看到,实际上是给处于子网内的所有ip发信。

  再来一个多播的例子,但是要实现这个多播并不容易,因为我不知道网络内有多少个多播组,就只好利用几个特殊的多播地址来验证了。

  对于多播地址,有几个特殊的多播地址被占用,他们是

  由于很多软件需要用到UDP协议,所以UDP协议必须通过某个标志用以区分不同的程序所需要的数据包。端口号的功能就在于此,例如某一个UDP程序A在系统中注册了3000端口,那么,以后从外面传进来的目的端口号为3000的UDP包都会交给该程序。端口号理论上可以有2^16这么多。因为它的长度是16个bit

  这是一个可选的选项,并不是所有的系统都对UDP数据包加以检验和数据(相对TCP协议的必须来说),但是RFC中标准要求,发送端应该计算检验和。

  UDP检验和覆盖UDP协议头和数据,这和IP的检验和是不同的,IP协议的检验和只是覆盖IP数据头,并不覆盖所有的数据。UDP和TCP都包含一个伪首部,这是为了计算检验和而摄制的。伪首部甚至还包含IP地址这样的IP协议里面都有的信息,目的是让UDP两次检查数据是否已经正确到达目的地。如果发送端没有打开检验和选项,而接收端计算检验和有差错,那么UDP数据将会被悄悄的丢掉(不送达),而不产生任何差错报文。

  UDP可以很长很长,可以有65535字节那么长。但是一般网络在传送的时候,一次一般传送不了那么长的协议(涉及到MTU的问题),就只好对数据分片,当然,这些是对UDP等上级协议透明的,UDP不需要关心IP协议层对数据如何分片,下一个章节将会稍微讨论一些分片的策略。

  IP在从上层接到数据以后,要根据IP地址来判断从那个接口发送数据(通过选),并进行MTU的查询,如果数据大小超过MTU就进行数据分片。数据的分片是对上层和下层透明,而数据也只是到达目的地还会被重新组装,不过不用担心,IP层提供了足够的信息进行数据的再组装。

  在IP头里面,16bit识别号唯一记录了一个IP包的ID,具有同一个ID的IP片将会被重新组装;而13位片偏移则记录了某IP片相对整个包的;而这两个表示中间的3bit标志则标示着该分片后面是否还有新的分片。这三个标示就组成了IP分片的所有信息,接受方就可以利用这些信息对IP数据进行重新组织(就算是后面的分片比前面的分片先到,这些信息也是足够了)。

  因为分片技术在网络上被经常的使用,所以伪造IP分片包进行的软件和人也就层出不穷。

  可以用Trancdroute程序来进行简单的MTU侦测。请参看教材。

  这是不常被人注意到的一个细节,这是针对一些系统地实现来说的。当ARP缓存还是空的时候。UDP在被发送之前一定要发送一个ARP请求来获得目的主机的MAC地址,如果这个UDP的数据包足够大,大到IP层一定要对其进行分片的时候,想象中,该UDP数据包的第一个分片会发出一个ARP查询请求,所有的分片都辉等到这个查询完成以后再发送。事实上是这样吗?

  结果是,某些系统会让每一个分片都发送一个ARP查询,所有的分片都在等待,但是接受到第一个回应的时候,主机却只发送了最后一个数据片而抛弃了其他,这实在是让人匪夷所思。这样,因为分片的数据不能被及时组装,接受主机将会在一段时间内将永远无法组装的IP数据包抛弃,并且发送组装超时的ICMP报文(其实很多系统不产生这个差错),以接受主机自己的接收端缓存不被那些永远得不到组装的分片充满。

  关于数据输入:通常服务器系统的每一个端口号都会和一块输入缓冲区对应,进来的输入根据先来后到的原则等待服务器的处理,所以难免会出现缓冲区溢出的问题,这种情况下,UDP数据包可能会被丢弃,而应用服务器程序本身并不知道这个问题。

  默认arch没有xorg.conf的(算是一个arch的风格吧,最小的配置,最大的灵活性),我们需要用Xorg-configure给出一个基本的xorg.conf的配置文件,然后把生成的文件拷贝到/etc/X11下面。有一些option我们需要手动加上,请manxorg.conf。

  要知道,arch的xorg软件包细化的厉害,如果你的X需要一些特别的驱动,就需要另外安装了,比如说显卡驱动,比如说鼠标板touchpad的驱动。运行如下的命令:

  192.168.11.1打不开剩下的配置,例如虚拟主机的配置,就都需要在/etc/httpd/conf/extra的相应配置文件中指定。

  php默认也是不加载任何模块的,我们要在/etc/php.ini里面把mysql模块加载进来。

  所讲到的东西在其他版本虽然也适用,但是这些设置在FC5或者Debian里面,这些都是不需要设置的,虽然做这些有些麻烦,这也体现了arch的定制性,arch带给我们一个快速的灵活的操作系统,这也是老手都喜欢它的一个重要的原因。

  把这三个协议放到一起学习是因为这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息。数据链层可以从ARP得到数据的传送信息,而从IP得到要传输的数据信息。

  IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输。要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制--这被认为是上层协议--TCP或UDP要做的事情。所以这也就出现了TCP是一个可靠的协议,而UDP就没有那么可靠的区别。这是后话,暂且不提

  如图所示

  挨个解释它是教科书的活计,我感兴趣的只是那八位的TTL字段,还记得这个字段是做什么的么?这个字段该数据包在穿过多少个由之后才会被抛弃(这里就体现出来IP协议包的不可靠性,它不数据被送达),某个ip数据包每穿过一个由器,该数据包的TTL数值就会减少1,当该数据包的TTL成为零,它就会被自动抛弃。这个字段的最大值也就是255,也就是说一个协议包也就在由器里面穿行255次就会被抛弃了,根据系统的不同,这个数字也不一样,一般是32或者是64,Tracerouter这个工具就是用这个原理工作的,tranceroute的-m选项要求最大值是255,也就是因为这个TTL在IP协议里面只有8bit。

  现在的ip版本号是4,所以也称作IPv4。现在还有IPv6,而且运用也越来越广泛了。

  当一个IP数据包准备好了的时候,IP数据包(或者说是由器)是如何将数据包送到目的地的呢?它是怎么选择一个合适的径来"送货"的呢?

  最特殊的情况是目的主机和主机直连,那么主机根本不用寻找由,直接把数据传递过去就可以了。至于是怎么直接传递的,这就要靠ARP协议了,后面会讲到。

  稍微一般一点的情况是,主机通过若干个由器(router)和目的主机连接。那么由器就要通过ip包的信息来为ip包寻找到一个合适的目标来进行传递,比如合适的主机,或者合适的由。由器或者主机将会用如下的方式来处理某一个IP数据包

  IP地址的定义是网络号+主机号。但是现在所有的主机都要求子网编址,也就是说,把主机号在细分成子网号+主机号。最终一个IP地址就成为网络号码+子网号+主机号。例如一个B类地址:...。一般情况下,这个IP地址的红色部分就是网络号,而蓝色部分就是子网号,绿色部分就是主机号。至于有多少位代表子网号这个问题上,这没有一个硬性的,取而代之的则是子网掩码,校园网相信大多数人都用过,在校园网的设定里面有一个255.255.255.0的东西,这就是子网掩码。子网掩码是由32bit的二进制数字序列,形式为是一连串的1和一连串的0,例如:255.255.255.0(二进制就是11111111.11111111.11111111.00000000)对于刚才的那个B类地址,因为210.30是网络号,那么后面的109.134就是子网号和主机号的组合,又因为子网掩码只有后八bit为0,所以主机号就是IP地址的后八个bit,就是134,而剩下的就是子网号码--109。

  还记得数据链层的以太网的协议中,每一个数据包都有一个MAC地址头么?我们知道每一块以太网卡都有一个MAC地址,这个地址是唯一的,那么IP包是如何知道这个MAC地址的?这就是ARP协议的工作。

  ARP(地址解析)协议是一种解析协议,本来主机是完全不知道这个IP对应的是哪个主机的哪个接口,当主机要发送一个IP包的时候,会首先查一下自己的ARP高速缓存(就是一个IP-MAC地址对应表缓存),如果查询的IP-MAC值对不存在,那么主机就向网络发送一个ARP协议包,这个包里面就有询的IP地址,而直接收到这份的包的所有主机都会查询自己的IP地址,如果收到包的某一个主机发现自己符合条件,那么就准备好一个包含自己的MAC地址的ARP包传送给发送ARP的主机,而主机拿到ARP包后会更新自己的ARP缓存(就是存放IP-MAC对应表的地方)。发送的主机就会用新的ARP缓存数据准备好数据链层的的数据包发送工作。

  一个典型的arp缓存信息如下,在任意一个系统里面用“arp-a”命令:

  ip大家都听说过。至于ARP和RARP,ARP叫做地址解析协议,是用IP地址换MAC地址的一种协议,而RARP则叫做逆地址解析协议,在tcp/ip协议的后面章节会介绍它们(在局域网里面用ARP协议可以很容易的搞瘫痪网络哦)

  数据链层的协议还是很多的,有我们最常用的以太网(就是平时我们用的网卡)协议,也有不太常见的令牌环,还有FDDI,当然,还有国内现在相当普及的PPP协议(就是adsl宽带),以及一个loopback协议。

  联系linux里面的ifconfig-a命令,这个命令通常会得到如下的结果

  其中,eth0就是以太网接口,而lo则是loopback接口。这也说明这个主机在网络链层上至少支持loopback协议和以太网协议。

  以太网(Ether-net)的定是指数字设备公司(DigitalEquipmentCorp.)、英特尔公司(IntelCorp.)和Xerox公司在1982年联合公布的一个标准,这个标准里面使用了一种称作CSMA/CD的接入方法。而IEEE802提供的标准集802.3(还有一部分定义到了802.2中)也提供了一个CSMA/CD的标准。这两个标准稍有不同,TCP/IP协议对这种情况的处理方式如下:

  可见,RFC1042在TCP/IP里面处于一个配角的地位。这两种不同的数据报格式请参考教材。

  ppp(点对点协议)是从SLIP的替代品。他们都提供了一种低速接入的解决方案。而每一种数据链层协议,都有一个MTU(最大传输单元)定义,在这个定义下面,如果IP数据报过大,则要进行分片(fragmentation),使得每片都小于MTU,注意PPP的MTU并不是一个物理定义,而是指一个逻辑定义(个人认为就是用程序控制)。可以用netstat来打印出MTU的结果,比如键入netstat-in

  最后说说那个环回接口(loopback)。平时我们用127.0.0.1来尝试自己的机器服务器好使不好使。走的就是这个loopback接口。对于环回接口,有如下三点值得注意:

  界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别。就好像圣经中打乱了各地人的口音,让他们无法合作一样。计算机使用者意识到,计算机只是单兵作战并不会发挥太大的作用。只有把它们联合起来,电脑才会发挥出它最大的潜力。于是人们就想方设法的用电线把电脑连接到了一起。

  但是简单的连到一起是远远不够的,就好像语言不同的两个人互相见了面,完全不能交流信息。因而他们需要定义一些共通的东西来进行交流,TCP/IP就是为此而生。TCP/IP不是一个协议,而是一个协议族的统称。里面包括了IP协议,IMCP协议,TCP协议,以及我们更加熟悉的http、ftp、pop3协议等等。电脑有了这些,就好像学会了外语一样,就可以和其他的计算机终端做的交流了。

  提到协议分层,我们很容易联想到ISO-OSI的七层协议经典架构,但是TCP/IP协议族的结构则稍有不同。如图所示

  TCP/IP协议族按照层次由上到下,层层包装。最的就是应用层了,这里面有http,ftp,等等我们熟悉的协议。而第二层则是传输层,著名的TCP和UDP协议就在这个层次(不要告诉我你没用过udp玩星际)。第三层是网络层,IP协议就在这里,它负责对数据加上IP地址和其他的数据(后面会讲到)以确定传输的目标。第四层是叫数据链层,这个层次为待传送的数据加入一个以太网协议头,并进行CRC编码,为最后的数据传输做准备。再往下则是硬件层次了,负责网络的传输,这个层次的定义包括网线的制式,网卡的定义等等(这些我们就不用关心了,我们也不做网卡),所以有些书并不把这个层次放在tcp/ip协议族里面,因为它几乎和tcp/ip协议的编写者没有任何的关系。发送协议的主机从上自下将数据按照协议封装,而接收数据的主机则按照协议从得到的数据包解开,最后拿到需要的数据。这种结构非常有栈的味道,所以某些文章也把tcp/ip协议族称为tcp/ip协议栈。

  网络上每一个节点都必须有一个的Internet地址(也叫做IP地址)。现在,通常使用的IP地址是一个32bit的数字,也就是我们常说的IPv4标准,这32bit的数字分成四组,也就是常见的255.255.255.255的样式。IPv4标准上,地址被分为五类,我们常用的是B类地址。具体的分类请参考其他文档。需要注意的是IP地址是网络号+主机号的组合,这非常重要。

  不知道有没有人和我一样这么想过,不会多线程,不会正则表达式,不会sokect,不会玩儿数据库。就不算是一个真的程序员,尤其是第一个,有一段时间甚至觉得,如果程序里面没有多线程,那简直是不够cool,不够专业。于是就看了看多线程,别说,在平时的开发里面还真能用上。

  平时写程序的时候,总是免不了要载入一个图片什么的。如果图片过大了,可能就要等到图片载入好了才能执行下面的代码,而这个时候,自己开发的应用程序就和死了一样,一点反应都没有,实际上它正在拼命的载入你给他的图片呢--连抱怨的机会都没有,因为只有一个线程啊,代码是在一个流水线上执行下来,如果不执行完的代码,就不能执行下面的,这就是单线程的弊端,死性,不灵活。</br>

  于是乎,多线程登场了,什么叫做多线程?顾名思意就是很多线,一般的程序是在一条线运行的,执行了前面的才能执行后面的。但是多线程看起来是在很多线上同时进行的,每根线都有自己的执行顺序。回到刚才的话题。我要载入一个图片,那就单开一条线程去载入图片,然后执行其他的代码。等到图片载入结束了,我在回过头来把图片显示出来,这就是多线程的好处,灵活。

  写在前面:最近在C++工具版问CDT使用方法的人不少。可见MinGW的用户和潜在用户还是有很多的。我现在把这个开发工具的使用方法总结出来,通过这篇文章,你应该可以学习到如何快速建立一个eclipse下面的C++开发。

  因为CDT是一个需要mingw支持的开发工具,所以有时候免不了需要一些linux命令,比如其自动建立的makefile文件里面就有rm命令。换句话说:如果没有linux模拟的支持,就无法正常的使用CDT来进行开发。

  作为CDT的开发后端,这里简单的讲一下mingw和cygwin的安装。这两种套件都采用网络安装的方式,只要在其网站下载相应的安装向导然后自己选择一些需要的或者感兴趣的套件安装就可以了。如果仅限于C++的基础开发,则推荐最小的配置是:

  mingw和cygwin安装本身是不需要做什么特别的配置,为了保险,可以在安装完成后检查一下windows的path变量是不是正确加入了mingw和cygwin的bin目录径。如果没有加入,加上它。然后在windows命令行下面键入:

  点击window菜单的prefrences会出现eclipse全局的配置对话框,CDT的配置在这个对话框的C/C++选项卡下面。很多选项用默认值就可以使用了,你可以在C/C++->Make->NewMakeProjects选项卡里面配置全局的编译,Make的特征。特别要注意这个选项卡里面的MakeBuilder下面的第一项。我们将要使用mingw作为编译后端,用的make工具也是mingw提供的,所以要把默认的命令修改为,其他的选项就看自己的喜好了。

  开发软件免不了要用第三方的库,CDT准备好了用户接口来挂载这些。所有的选项都在Properties里面(右击当前的工程)。ToolSettings下面有Compiler和linker的命令选项提供了这些接口。如果打算预先定义一些Macro,则可以在Compiler选项卡的PreProcesser里面的Definedsymbols里面制定,CDT会生成-DMarcro样式的参数。

  至此,一个基本可用的C++开发就算建立好了。但是个人认为CDT并不是很成熟的,缓慢的运行、调试速度和有限的代码提示功能是制约它的一个重要原因。除非你别无选择,否则还是以不要使用这个插件为上策。尽管如此,这个插件还是为我们开发C++工程有提供了一种新的工具,那些为此付出辛勤劳动的程序员是值得尊敬的。

  state之间的跳转和转换常复杂的,有时一些state可能要跳转的目标state有几十个,这个时候我们需要一个管理类(StateManager)来统一的管理这些state的切换,例如目标state的初始化和申请跳转state的结束处理,以及一些state间共享数据的存储和处理。与其称这个Manager为管理类,不如说是一个中间类,它实现了state之间的解隅,使得各个state之间不比知道targetstate的具体信息,而只要向Manager申请跳转就可以了。使得各个state的模块化更好,更加的灵活

  既然state要教给一个manager来管理,那么自然的,这些state都应该从一个父类继承下来,这样manager并不需要知道很多子类的信息,一个最单纯的manager只要只要管理一个这样的基类的指针就可以了。另外,我们还可以统一的把state的一些共有的属性放在这里

  state并不需要总是被申请,这样可能会造成管理上的混乱,state资源的申请也不应该可以任意进行,事实上,state的申请权限应该只有Manager才有,并且有且只有一次。在这样的情况下,state的构造函数似乎应该被声明为protectedorprivate,而Manager应该被声明为state的友元,但是友元被看成是类的封装性的一种做法,这一点上,我很矛盾,所以在这一条上我只能采取一种的态度。

  state可以说是if-else的一种替代品,极端的情况下面state可以让你的程序中if-else程序块消失得无影无踪,但是,这并不是银弹。state对于状态可预知的情况下非常有效,但是对于state不可预知,或者相似的state数量太多。过多的state会造成class的粒度过细,程序反而不简洁。在这样的情况下,你应该考虑使用if-else程序块来替代state。

  有这样的一个程序,它可以生成任意形状的多边形,而多边形的各个节点是可以移动的,问题就来了。

  我并不知道用户将要使用多少个节点的多边形,因此我无法的创建那么多相应的state来使得这样一个程序正常工作。state大多数都是确定的,对于不确定的,state似乎为力,例如此例

  一种解决方法是我利用Manager传递给state一个state参数,让state有机会知道用户的操作意图,在这个例子里面是让state知道用户打算操作某一个节点,而state根据这个state参数来处理用户的操作,比如说,state得到的是用户操作的某一个点的index,而state只要写

  就可以,从而避免了state过多出现的问题

不良信息举报Q:2000617

软路由

不良信息举报Q:2000617|Archiver|ROS软路由论坛 ROSABC.com 网络方案网络工程交流

GMT+8, 2024-5-19 12:21 , Processed in 0.270431 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部