网络协议(4)--ICMP协议
互联网控制消息协议(英文:Internet Control Message Protocol,ICMP)是互联网协议族的核心协议之一。定义在 RFC 792 文档中。
ICMP 的消息大致可以分为两类:一类是差错报文,即通知出错原因的错误消息(如 traceroute),另一类是查询报文,即用于诊断的查询消息(如 ping)。
使用 ICMP 协议的典型应用有 ping 和 traceroute(windows 上叫 tracert)。
互联网控制消息协议(英文:Internet Control Message Protocol,ICMP)是互联网协议族的核心协议之一。定义在 RFC 792 文档中。
ICMP 的消息大致可以分为两类:一类是差错报文,即通知出错原因的错误消息(如 traceroute),另一类是查询报文,即用于诊断的查询消息(如 ping)。
使用 ICMP 协议的典型应用有 ping 和 traceroute(windows 上叫 tracert)。
IP 协议是 TCP/IP 协议族中最核心的协议。所有的 TCP、UDP、ICMP、IGMP 数据都以 IP 数据报的格式传输。
ARP (Address Resolution Protocol) 地址解析协议,位于 TCP/IP 协议栈中的链路层。
当局域网内主机间(或者是主机与网关间)需要通信时,通过使用 ARP 协议获取目标 IP 地址所对应的硬件 MAC 地址,然后在主机间通过 MAC 地址来完成数据包的发送和接收。
完整的OSI协议总共有7层,如下图所示:
在实际应用中,业界又产生了简化的五层 TPC/IP 协议栈,将 OSI 协议栈中的会话层、表示层、应用层统称为应用层。
在五层TCP/IP协议栈的基础上,进一步将物理层、数据链路层统称为链路层。

IP 地址相当于互联网上的门牌号,计算机在启动的时候可以从磁盘(无盘系统例外)上读取该主机的 IP 配置。
IP 地址由 4 个字节(也就是 32 位)的二进制码组成,包含了网络号( net-id )和主机号( host-id )。但现实中,我们经常还需要再继续划分“子网”,这时就需要借用主机号的一部分充任子网号,这样 IP 地址也就可以看成由标准网络号、子网号、主机号3 部分组成的,即IP地址=标准网络号+子网号+主机号。
网络号、子网号、主机号三者间的关系,形象的描述如下:假设你的住址 IP 是
武汉市文治街16号,那么,
IP 地址 = 武汉市文治街 16 号
网络号 = 武汉市
子网号 = 文治街
主机号 = 16 号
| IP 地址种类 | 二进制组成(前缀位+网络位+主机位) | IP 范围 | 网络数 | 主机数/网络 |
|---|---|---|---|---|
| A 类地址 | 0+7 位网络号+24 位主机号 |
1.0.0.0 - 127.255.255.255 | $2^7-2$ | $2^{24}-2$ |
| B 类地址 | 10+14 位网络号+16 位主机号 |
128.0.0.0 - 191.255.255.255 | $2^{14}-1$ | $2^{16}-2$ |
| C 类地址 | 110+21 位网络号+8 位主机号 |
192.0.0.0 - 223.255.255.255 | $2^{21}-1$ | $2^8-2$ |
| D 类地址 | 1110+多播地址(用于多播) |
224.0.0.0 - 239.255.255.255 | - | - |
| E 类地址 | 1111+保留位(不开放, 保留使用) |
240.0.0.0-249.255.255.255 | - | - |
从表中可以看出,A 类 IP 的第 1 字节的第 1 位(二进制位)必须是 0,所以 A 类 IP 的第一个整数的范围是0000 0000 ~ 01111 11111,转换为十进制就是0 ~ 127,以此类推。
网络数就是一种网络的子网数, 比如 A 类地址, 可以分为多少个子网。看表格可以推出网络数的计算公式为: $2^{网络号位数}$。
规定网络地址全为0的 IP 地址是保留地址,意思是“本网络”。
0.0.0.0 是不指派的,而可以指派的最小网络是 1.0.0.0;网络地址为 127 的 A 类 IP 地址保留作为本地软件环回测试本主机的进程之间的通信(比如常用的 127.0.0.1,但实际上网络地址为127的都可以用作本地环回地址)。所以 A 类地址网络数为 $2^7-2$。128.0.0.0 是不指派的,而可以指派的最小网络是 128.1.0.0,所以 B 类地址网络数是 $2^{14} - 1$。192.0.0.0 是不指派的,而可以指派的最小网络是 192.0.1.0,所以 C 类地址网络数是 $2^{21}-1$。主机数就是一个子网里面可以容纳多少台主机。从上面表格可以推算出主机数的计算公式为: 2^主机号位数-2(主机号全为 0 表示该网络,而主机号全为 1 表示广播地址,所以要排除掉这两个)。比如 A 类地址 1.0.0.0 表示主机所在的网段的网络地址, 1.255.255.255 为该网段的广播地址。
经常可以看到192.168.1.101这类的 IP 地址, 这些是私有 IP 地址, 专用地址, 也就是局域网内使用的的 IP 地址。
公网 IP 地址是需要向有关部门申请备案的,私有 IP 地址不用申请, 但是仅限内网使用, 也节约公网 IP。
| IP 地址种类 | 私有 IP 范围 |
|---|---|
| A 类地址 | 10.0.0.0 - 10.255.255.255 |
| B 类地址 | 172.16.0.0 - 172.31.255.255 |
| C 类地址 | 192.168.0.0 - 192.168.255.255 |
路由器看到专用地址就不转发,所以说专用地址作为目的地址是不可能在因特网上传送的。专用 IP 地址也可叫做可重用地址。
那么,问题来了,如果配置了这些专用地址的主机想和因特网上的主机通信,需要怎么办呢?
NAT(network address translation: 网络地址转换)在这种情况下就应运而生了。NAT 就是将这种地址转换成有效的外部全球 IP 地址,使得整个专用网只需要一个全球 IP 地址就可以与因特网联通。
IP地址=标准网络号+子网号+主机号。从 IP 分类可以很容易确定“标准网络号”,32bit的 IP 地址除去前面的“标准网络号”之后,剩下的就是“子网号”和“主机号”,那么怎么确定“子网号”和“主机号”呢? 这就需要借助“子网掩码”了。
子网掩码也是一个 32bit(xxx.xxx.xxx.xxx)的值,其中值为 1 的 bit 留给“标准网络号”和“子网号”,为 0 的 bit 留给“主机号”。我们可以将子网掩码和 IP 地址进行二进制“与运算”,通过得到的结果来确定“子网号”。
以 C 类 IP 地址为例,对于规范的 C 类 IP 地址来说,规范子网掩码为255.255.255.0,即用 32 比特 IP 地址的前 24 比特标识网络号,后 8 比特标识主机号。因而,每个 C 类网络下共可容纳 254 台主机($2^8-2$)。
如今,我们打算借用 2 比特的主机号来充任子网络号。C 类网络地址210.31.233.0,我们借用 2 比特的主机号来充当子网号,子网的数目为$2^2-2$(子网号无法全为 0 或 1,所以减 2).

为了借用原来 8 位主机号中的前 2 位充任子网络号,于是采用了非规范的子网掩 255.255.255.192。
采用了新的子网掩码后,借用的 2 位子网号可以用来标识两个子网:01 子网和 10 子网(子网号无法全为 0 或 1,因而 00、11 子网无法用)。
对于上图的 01 子网来说,其网络号的点分十进制的方式为:210.31.233.64,该子网的最小 IP 地址为:210.31.233.65,最大 IP 地址为:210.31.233.126(主机号全为 1 的是广播地址,需要排除),共可容纳 62 台主机。对该子网的直接广播地址为:210.31.233.127(主机号全为 1)。
经常见到像
192.168.1.0/24这样的写法,它的意思是网络号为192.168.1.0;子网掩码为 24 位,即111111111 111111111 111111111 00000000,转为点分十进制就为255.255.255.0,可以拥有的主机数为$2^8$-2.
你的住址 IP 是武汉市洪山区文治街16号,你的父母只允许你和文治街的小朋友(同一个子网)一起玩耍,如果你想要去和别的街道(别的子网)的小朋友玩耍,你就需要经过你的父母的同意,由你的父母带你过去,这时候你的父母就充当了网关的角色,没有你的父母,你就不能和其他街道(其他子网)的小朋友玩耍。
封装英文:Encapsulation
解封装英文:Demultiplexing
当应用程序使用网络传送数据时,数据按照协议栈从上到下的顺序,逐次通过每一层。其中每一层对收到的数据都要增加一些首部信息(有时还增加尾部信息)。最终生成的一串比特流将通过以太网来传输,我们称这串比特流叫帧。
如图:
当数据报到达链路层时,链路层也要对 IP 数据包封装进行包装。链路层对 IP 数据包封装的方式主要有以太网IP数据包封装(RFC894)、IEEE 802 IP数据报封装(RFC1042)两种,最常使用的封装格式是以太网 IP 数据包封装(RFC894)。下图显示了这两种不同形式的封装格式:
从图中可以看到以太网封装限制了数据帧的最大长度为 1500 字节,这个限制叫做 MTU,最大传输单元(详见第四节)。
接收端收到帧之后,按照和上面相反的顺序(协议栈从下到上)来解包,依次解析每一层加入的头部(或尾部),最终将原始数据传给最上层应用程序。
如图:
因为传输层的 TCP、UDP、ICMP 等都有可能向网络层 IP 协议传送数据,这样在 IP 协议层解包的时候,需要知道这个包对应的上层协议是哪一个,因此 IP 协议必须在生成的 IP 首部加入某种标识,以表明数据的上一层的具体协议。为此,IP 在首部中存入了一个长度为 8bit 的数值,称作协议域。常见的 IP 协议号有:
1 表示 ICMP 协议,2 表示 IGMP 协议,6 表示 TCP 协议,17 表示 UDP 协议。
完整的 IP 协议号见:IP 协议号列表
前面第三节提到了以太网封装限制了数据帧的长度为 1500 字节,这个限制是在链路层封装 IP 数据报时作的。如果 IP 层的数据报比链路层的这个 MTU 值大,那么 IP 层就需要分片(英文:fragmentation),把数据报分成若干片,保证每一片的大小都小于 MTU 值。
1 | netsh interface ipv4 show subinterfaces |

1 | netsh interface ipv4 set subinterface "本地连接" mtu=1480 store=persistent |
文章参考:
https://m.vipcn.com/a/360973/ > https://ahaochan.github.io/posts/IP_address,_subnet_mask,_gateway_Introduction.html > https://www.zhihu.com/question/20717354
《TCP/IP 详解 卷 1:协议》在线阅读地址:http://www.52im.net/topic-tcpipvol1.html
文章图片带有“CSDN”水印的说明:
由于该文章和图片最初发表在我的CSDN 博客中,因此图片被 CSDN 自动添加了水印。
成功的唯一秘诀就是钻空子。钻职场人际关系的空子、钻市场监管的空子、钻信息不对称的空子,钻你发现的一切空子的空子。当然,坚持、努力、选择这些因素,对于成功也很重要,但算不上秘诀。只有钻空子才是唯一的秘诀。
不要做永远正确的穷人。少跟人争辩,你觉得对就去做,做成了自然别人就闭嘴了。说服别人并没有实际的意义,浪费口舌和时间。当然,利益相关的事情,有人冤枉你的情况除外。
脸皮变厚一倍,成功的可能性要翻倍。不要怕丢脸,你觉得丢脸的事情,大家其实压根不在乎,丢脸多半是你个人的臆想。
项目不做调研,就像嫖娼不戴套,非常危险。任何项目启动前一定要做适当的调研,哪怕很粗糙,也远胜于无。
创业做生意就是要抄,抄产品、抄模式、抄架构,这是规避风险,减少试错成本的最好方法。但是也不能全抄。大原则是:拿得准的环节创新,拿不准的地方抄。
每个月花半天时间,扫描和梳理自己所在领域和区域的行业新机会。
有枣没枣,打一竿子。多去做一些尝试。不一定每一件事都要努力去做,但那些舒适区外的事情,可以试着去做。
大家都去找金矿的时候,给淘金的人卖铲子就是最好的生意,多考虑快速增长行业的周边生意。
卖手机不如修手机,修手机不如做二手回收。一个行业越是信息不对称,越是不标准化,它的利润就越高,赚钱的可能性就越大。
要投资一个领域,下面两个条件至少要一个条件成立:1. 你自己懂行;2. 你能找到懂行又靠谱的人来帮你把关。
不要用个人的好恶代替商业逻辑。如果你觉得罗辑思维、咪蒙、比特币都是骗子,那你永远看不到背后的需求、机会和行业红利。
做营销就和做小姐一样,越low的方式反倒越有效。与其扭扭捏捏、故作逼格,不如大大方方简单粗暴、赤裸相待。
遇到自己不懂或者没听过的新名词,用手机记下来。有空可以研究一下,说不定里面有新的机会和思路。
对于赚钱的事,多琢磨,多尝试。当你第一次尝到甜头,你就走在一条快车道上了。
让你觉得听了不舒服的话,往往是真话。别人对你的有价值的批评,往往是你成长和进步的机会。
减少无效思考。80%的人都是无能的,即使是有能力的人当中,80%的思考也是无效的。尽可能减少无效的思考时间,多把精力和时间投入到行动中。
别被那些一夜暴富的事情忽悠了,相信时间,相信积累,顺着大趋势慢慢做,总会起来。
选择比努力更重要。思考方式的转变比能力提升更重要,这方面的学习和研究很有价值。
如果你无法释怀过去的痛苦,不要责怪你自己,尽可能安排一下未来生活的兴奋点。
忧虑的时候尽可能保持忙碌,把身体的能量用完了,就没时间、精力忧虑了。
每周至少约一个对自己事业、生活有帮助的朋友吃饭。
人与人之间很难真正理解,你也不需要这么多人理解你,也不要为了让别人理解你做太多尝试。专注于提升自己的实力,多做一些让别人敬佩你的事情。
相比于认清世界,更难的是认清自己。对自己有一个清晰的认识后,需要做取舍做选择,才会有判断依据。
靠谱不仅是一种人格,也是一种营销策略。因为这个世界大部分人都不靠谱,你要是相对靠谱,好的资源、机会都会首先想到你、找到你。能在混沌一片的世界里快速把自己的品牌营销出去。
思想深度和快乐是成反比的,除了赚钱相关的事情,其他事情没必要深究,徒增烦恼。不要觉得减少就变成一个快乐的笨蛋了,你思考太多、忧虑太多,你只是变成一个忧心忡忡的笨蛋罢了。
学习最重要的,不是把10分的精力都花在吸收新知识上,而是3分学习,7分练习和实践。
简单的事情反复做,就能成长;复杂的事情简单做,就能成功。同一个技能反复练习100次,那个技能就是你的;同一个领域的事情做对100次,那个领域的钱就是你的。
迷茫的时候,就把能做好的事情踏实做好就行。多关注自己力所能及的小事,小成功积累多了,就有大成功的机会。。
人生常常就像堵车,心里别添堵。很多时候堵在里面,你也不要心急。能走几步走几步,走不动的时候歇着,等车流慢慢恢复了,又继续走。
有责任感有担当的人,往往都活得比较累,因为要操心的事儿太多。你如果是这样的人,接受这样的事实,尽可能坦然面对事业、生活、家庭中的苦与乐。
做人不要太容易多愁善感,不然容易成为loser。
生活的常态就是平淡,但是我们在规划未来的时候,尽可能还是为生活安排一些兴奋点。
每个人的生活都需要有一个支点,不管是让你充满成就感的事业、还是你疼爱的爱人,还是你的温暖家庭,还是你的知心挚友、老师、贵人,或者是一个爱好。至少要有一个这样的支点,能够支撑起你的生命。即使在你迷茫、无助、悲伤的时候,这个支点能支撑你走过最艰难的时刻。能让你的精神随时有地方可以倚靠。
转载自:
程序员薪水有高有低,有的人一个月可能拿30K、50K,有的人可能只有2K、3K。同样有五年工作经验的程序员,可能一个人每月拿20K,一个拿5K。是什么因素导致了这种差异?我特意总结了容易导致薪水低的九大行为表现,避开这些大坑,你就离高薪不远了。
他不懂得只有春天播种,秋天才会有收获。刚刚付出一点点,甚至还没有付出,就想要得到回报。技术刚刚掌握,能一边百度一边干活了就觉得该拿到多少多少钱了。找工作先想着多少多少钱,入职了没干几个月就想着要加多少多少钱,干了没几个月,薪水要是没涨,就放弃了,准备通过跳槽加薪,不跳槽的话,往往也会因为没加薪而牢骚满腹,工作敷衍了事。
一个程序员的价值,是通过他带给公司的价值体现的。先给公司带来了价值,然后才会反过来在薪水上体现出自己的价值。公司都很现实,很少会为你的潜力买单,在你还没有体现出价值时就给你很高的薪水。
在生活和工作中,一定要懂得付出,不要那么急功近利,马上想得到回报。天下没有白吃的午餐,你想获得什么,就得先付出什么。唯有种下种子,然后浇水、施肥、除草、杀虫,然后才能等来收获。
很少有哪个岗位的人像程序员这样需要持续不断的学习,软件开发的技术日新月异,而每一项技术又往往博大精深,不持续、深入钻研是很难掌握的,更别谈精通了。如果你对一项技术不能深刻理解熟练应用,表现出来的水准仅仅是能干活、还行,那很难说会有公司愿意为“还行”付出大的代价,只有脱颖而出,才可能备受重视。
假如你对学习、掌握、精通技术没有兴趣,面对不断涌现的新语言新技术新框架没有学习欲望,那但就软件开发这个工作而言,你不但眼下不太可能拿到高薪,将来也不会。在这样一个快速变化的时代,只有不断地学习才不会被抛弃。
虽然我们都知道努力学习可以改变我们的技能水平,持续努力不懈坚持可以让自己有所建树,可还是有很多人浅尝辄止,三天打鱼两天晒网,搞两下能Run就放下了。
人和人在聪明才智上的差距并没有想象中大,甚至很多时候,从大多数人的努力程度之低来看,根本还轮不到拼天赋。如果两个人的实力半斤八两的话,热情工作努力坚持的人,一定比较容易成功。
做事拈轻怕重,不愿挑战。殊不知能力就是在不断挑战不断突破自己的过程中历练出来的。在一个公司里面,经常承担高难度任务的程序员,一定是成长比较快的,薪水增长也一定是比较快的。越是困难的事情,越能体现出个人价值,也越能带给个人成长。
万事起头难,不要害怕困难。事情做不好往往不是因为没有能力,大都是由于缺乏恒心。只要不怕困难,坚持前行,一定会有不一样的收获。
事业就像女人,谁去追求,谁就能得手。金钱也一样。
工作上不管什么事儿,反正不是自己的事儿,缺乏责任心,干好干不好都无所谓,对交付承诺、对产品质量都不在意,没什么事儿能让他上心。
一个人的责任心如何,决定着他在工作中的态度,决定着其事业的好坏和成败。如果一个人没有责任心,即使他有再大的能耐,也不一定能做出好的成绩来。
工作稍有不顺,就怨气沸腾,这个怎么怎么样,那个怎么怎么样,而我怎么就这样,任务不公平,资源不公平,那谁谁不支持我,那谁谁不配合……
抱怨不能使事情变好,反之,它会让负面情绪蔓延,蚕食你的精力和时间,让你产出更低。成功者永不抱怨,抱怨者永不成功。立刻停止抱怨,早一分钟停止,你就离目标近一分钟。
每个人的一天都只有24小时,人和人的差别就在于如何利用时间上。
有的人每周都有目标,每天都有计划,早上起来会想今天要做的几件重要的事,晚上会回顾今天完成的事,总结干成了什么干坏了什么,还会有计划的学习新知识新技能,这样日积月累不断坚持,每一天都是高效的,每一天都朝着更丰富更完美的自己前进。
而有的人则漫无目的,走哪算哪,到了公司,上午基本做不成事儿,到下午了还不知道要做什么,晚上也发愁如何消磨时间……
虽然工作的一大目的是获取薪水,养活自己以及供给家庭所需;但是,这只是工作最直接的报偿,同时也是最低级的目标。
如果我们为薪水而工作,将注定我们是短视的,也将注定受到最深的伤害。假如你看不到工资以外的东西,斤斤计较于薪水、福利、职位等,那外界的些微风吹草动就可能让你像浮萍一样飘来荡去,你很快就会失去平衡,失去信心,失去热情,失去平和,进而在工作时总是采取一种应付了事的态度,能少做就少做,能躲避就躲避,觉得只要对得起自己的那份薪水就成了。长此以往,你追求的高薪水反倒得不到。
我们进入一个公司工作,是为了自己,不是薪水也不是别人,比薪水更重要的,是成长和成就自己的机会。我们一定要明白,公司、企业、组织,都是我们锻炼自己、修炼自我的平台,我们不是为薪水工作、不是为老板工作、不是为家人工作,是为实现自我而工作,是为更完美的自己而工作。
唯有志存高远,方能风行天下。
有一部分人从事软件开发工作,并不是因为喜欢,也没有干着干着从不喜欢变成喜欢。他们可能是喜欢软件开发附带的高薪水——平均薪水比其他行业高。人做一件自己不喜欢的事情时,心理上没有亲近感,不会想着怎样把事情做得更好,往往是差不多就成了,不太可能有精益求精积极向上的追求。因为在做不喜欢的事情时,情感上是拒绝的,情绪上是想逃离的,总想着早点儿完事儿拉倒,每一天去单位时不是充满期待,而是各种担忧、烦躁、畏惧,到了单位,稍有困难或不顺心,就会消极、抱怨、抵触、拒绝……
做喜欢的事,能最大可能发挥一个人的潜能和热情,会最快速地通向成功成就自己。而做不喜欢的事,一开始就注定了事倍功半,最后也往往会是痛苦不堪或半途而废。
转载自:
本文通过一个实例来讲解如何使用 WinDbg 来调试 Windows Mutex 死锁的问题。
在进行数据库开发时,我们可能需要写很多存储过程,本文提供一个存储过程的模板,通过该模板可以简化存储过程的开发。