独钓寒江雪

用C++的优雅,驯服Windows的狂野

互联网控制消息协议(英文:Internet Control Message Protocol,ICMP)是互联网协议族的核心协议之一。定义在 RFC 792 文档中。
ICMP 的消息大致可以分为两类:一类是差错报文,即通知出错原因的错误消息(如 traceroute),另一类是查询报文,即用于诊断的查询消息(如 ping)。
使用 ICMP 协议的典型应用有 ping 和 traceroute(windows 上叫 tracert)。

阅读全文 »

ARP (Address Resolution Protocol) 地址解析协议,位于 TCP/IP 协议栈中的链路层。

当局域网内主机间(或者是主机与网关间)需要通信时,通过使用 ARP 协议获取目标 IP 地址所对应的硬件 MAC 地址,然后在主机间通过 MAC 地址来完成数据包的发送和接收。

阅读全文 »

一、协议栈

1.1 七层OSI协议栈

完整的OSI协议总共有7层,如下图所示:

1.2 五层TCP/IP协议栈

在实际应用中,业界又产生了简化的五层 TPC/IP 协议栈,将 OSI 协议栈中的会话层、表示层、应用层统称为应用层。

1.3 四层TCP/IP协议栈

在五层TCP/IP协议栈的基础上,进一步将物理层、数据链路层统称为链路层。

二、IP 地址、子网掩码、网关

2.1 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 地址是保留地址,意思是“本网络”。

  • 在 A 类地址中,实际上 0.0.0.0 是不指派的,而可以指派的最小网络是 1.0.0.0;网络地址为 127 的 A 类 IP 地址保留作为本地软件环回测试本主机的进程之间的通信(比如常用的 127.0.0.1但实际上网络地址为127的都可以用作本地环回地址)。所以 A 类地址网络数为 $2^7-2$。
  • 在 B 类地址中,实际上 128.0.0.0 是不指派的,而可以指派的最小网络是 128.1.0.0,所以 B 类地址网络数是 $2^{14} - 1$。
  • 在 C 类地址中,实际上 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 为该网段的广播地址。

2.2 私有 IP 地址

经常可以看到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 地址就可以与因特网联通。

2.3 子网掩码

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.

2.3 网关的作用

你的住址 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 协议号列表

四、MTU

前面第三节提到了以太网封装限制了数据帧的长度为 1500 字节,这个限制是在链路层封装 IP 数据报时作的。如果 IP 层的数据报比链路层的这个 MTU 值大,那么 IP 层就需要分片(英文:fragmentation),把数据报分成若干片,保证每一片的大小都小于 MTU 值。

windows 系统修改 MTU 值

  • 查询当前 MTU 值
1
netsh interface ipv4 show subinterfaces

  • 修改 MTU 值
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 自动添加了水印。

功能

DECLARE...HANDLER语法如下:

1
2
3
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement

功能概括起来就是:
在一个或者多个condition_value条件满足时,先执行statement语句,然后执行handler_action动作

阅读全文 »

  1. 成功的唯一秘诀就是钻空子。钻职场人际关系的空子、钻市场监管的空子、钻信息不对称的空子,钻你发现的一切空子的空子。当然,坚持、努力、选择这些因素,对于成功也很重要,但算不上秘诀。只有钻空子才是唯一的秘诀。

  2. 不要做永远正确的穷人。少跟人争辩,你觉得对就去做,做成了自然别人就闭嘴了。说服别人并没有实际的意义,浪费口舌和时间。当然,利益相关的事情,有人冤枉你的情况除外。

  3. 脸皮变厚一倍,成功的可能性要翻倍。不要怕丢脸,你觉得丢脸的事情,大家其实压根不在乎,丢脸多半是你个人的臆想。

  4. 项目不做调研,就像嫖娼不戴套,非常危险。任何项目启动前一定要做适当的调研,哪怕很粗糙,也远胜于无。

  5. 创业做生意就是要抄,抄产品、抄模式、抄架构,这是规避风险,减少试错成本的最好方法。但是也不能全抄。大原则是:拿得准的环节创新,拿不准的地方抄。

  6. 每个月花半天时间,扫描和梳理自己所在领域和区域的行业新机会。

  7. 有枣没枣,打一竿子。多去做一些尝试。不一定每一件事都要努力去做,但那些舒适区外的事情,可以试着去做。

  8. 大家都去找金矿的时候,给淘金的人卖铲子就是最好的生意,多考虑快速增长行业的周边生意。

  9. 卖手机不如修手机,修手机不如做二手回收。一个行业越是信息不对称,越是不标准化,它的利润就越高,赚钱的可能性就越大。

  10. 要投资一个领域,下面两个条件至少要一个条件成立:1. 你自己懂行;2. 你能找到懂行又靠谱的人来帮你把关。

  11. 不要用个人的好恶代替商业逻辑。如果你觉得罗辑思维、咪蒙、比特币都是骗子,那你永远看不到背后的需求、机会和行业红利。

  12. 做营销就和做小姐一样,越low的方式反倒越有效。与其扭扭捏捏、故作逼格,不如大大方方简单粗暴、赤裸相待。

  13. 遇到自己不懂或者没听过的新名词,用手机记下来。有空可以研究一下,说不定里面有新的机会和思路。

  14. 对于赚钱的事,多琢磨,多尝试。当你第一次尝到甜头,你就走在一条快车道上了。

  15. 让你觉得听了不舒服的话,往往是真话。别人对你的有价值的批评,往往是你成长和进步的机会。

  16. 减少无效思考。80%的人都是无能的,即使是有能力的人当中,80%的思考也是无效的。尽可能减少无效的思考时间,多把精力和时间投入到行动中。

  17. 别被那些一夜暴富的事情忽悠了,相信时间,相信积累,顺着大趋势慢慢做,总会起来。

  18. 选择比努力更重要。思考方式的转变比能力提升更重要,这方面的学习和研究很有价值。

  19. 如果你无法释怀过去的痛苦,不要责怪你自己,尽可能安排一下未来生活的兴奋点。

  20. 忧虑的时候尽可能保持忙碌,把身体的能量用完了,就没时间、精力忧虑了。

  21. 每周至少约一个对自己事业、生活有帮助的朋友吃饭。

  22. 人与人之间很难真正理解,你也不需要这么多人理解你,也不要为了让别人理解你做太多尝试。专注于提升自己的实力,多做一些让别人敬佩你的事情。

  23. 相比于认清世界,更难的是认清自己。对自己有一个清晰的认识后,需要做取舍做选择,才会有判断依据。

  24. 靠谱不仅是一种人格,也是一种营销策略。因为这个世界大部分人都不靠谱,你要是相对靠谱,好的资源、机会都会首先想到你、找到你。能在混沌一片的世界里快速把自己的品牌营销出去。

  25. 思想深度和快乐是成反比的,除了赚钱相关的事情,其他事情没必要深究,徒增烦恼。不要觉得减少就变成一个快乐的笨蛋了,你思考太多、忧虑太多,你只是变成一个忧心忡忡的笨蛋罢了。

  26. 学习最重要的,不是把10分的精力都花在吸收新知识上,而是3分学习,7分练习和实践。

  27. 简单的事情反复做,就能成长;复杂的事情简单做,就能成功。同一个技能反复练习100次,那个技能就是你的;同一个领域的事情做对100次,那个领域的钱就是你的。

  28. 迷茫的时候,就把能做好的事情踏实做好就行。多关注自己力所能及的小事,小成功积累多了,就有大成功的机会。。

  29. 人生常常就像堵车,心里别添堵。很多时候堵在里面,你也不要心急。能走几步走几步,走不动的时候歇着,等车流慢慢恢复了,又继续走。

  30. 有责任感有担当的人,往往都活得比较累,因为要操心的事儿太多。你如果是这样的人,接受这样的事实,尽可能坦然面对事业、生活、家庭中的苦与乐。

  31. 做人不要太容易多愁善感,不然容易成为loser。

  32. 生活的常态就是平淡,但是我们在规划未来的时候,尽可能还是为生活安排一些兴奋点。

  33. 每个人的生活都需要有一个支点,不管是让你充满成就感的事业、还是你疼爱的爱人,还是你的温暖家庭,还是你的知心挚友、老师、贵人,或者是一个爱好。至少要有一个这样的支点,能够支撑起你的生命。即使在你迷茫、无助、悲伤的时候,这个支点能支撑你走过最艰难的时刻。能让你的精神随时有地方可以倚靠。

转载自:

http://mp.weixin.qq.com/s/PjlLbikJHSM4PKwpmTkL9g

程序员薪水有高有低,有的人一个月可能拿30K、50K,有的人可能只有2K、3K。同样有五年工作经验的程序员,可能一个人每月拿20K,一个拿5K。是什么因素导致了这种差异?我特意总结了容易导致薪水低的九大行为表现,避开这些大坑,你就离高薪不远了。

1. 习惯即刻回报

他不懂得只有春天播种,秋天才会有收获。刚刚付出一点点,甚至还没有付出,就想要得到回报。技术刚刚掌握,能一边百度一边干活了就觉得该拿到多少多少钱了。找工作先想着多少多少钱,入职了没干几个月就想着要加多少多少钱,干了没几个月,薪水要是没涨,就放弃了,准备通过跳槽加薪,不跳槽的话,往往也会因为没加薪而牢骚满腹,工作敷衍了事。

一个程序员的价值,是通过他带给公司的价值体现的。先给公司带来了价值,然后才会反过来在薪水上体现出自己的价值。公司都很现实,很少会为你的潜力买单,在你还没有体现出价值时就给你很高的薪水。

在生活和工作中,一定要懂得付出,不要那么急功近利,马上想得到回报。天下没有白吃的午餐,你想获得什么,就得先付出什么。唯有种下种子,然后浇水、施肥、除草、杀虫,然后才能等来收获。

2. 缺乏学习热情

很少有哪个岗位的人像程序员这样需要持续不断的学习,软件开发的技术日新月异,而每一项技术又往往博大精深,不持续、深入钻研是很难掌握的,更别谈精通了。如果你对一项技术不能深刻理解熟练应用,表现出来的水准仅仅是能干活、还行,那很难说会有公司愿意为“还行”付出大的代价,只有脱颖而出,才可能备受重视。

假如你对学习、掌握、精通技术没有兴趣,面对不断涌现的新语言新技术新框架没有学习欲望,那但就软件开发这个工作而言,你不但眼下不太可能拿到高薪,将来也不会。在这样一个快速变化的时代,只有不断地学习才不会被抛弃。

3. 不够努力

虽然我们都知道努力学习可以改变我们的技能水平,持续努力不懈坚持可以让自己有所建树,可还是有很多人浅尝辄止,三天打鱼两天晒网,搞两下能Run就放下了。

人和人在聪明才智上的差距并没有想象中大,甚至很多时候,从大多数人的努力程度之低来看,根本还轮不到拼天赋。如果两个人的实力半斤八两的话,热情工作努力坚持的人,一定比较容易成功。

4. 畏难

做事拈轻怕重,不愿挑战。殊不知能力就是在不断挑战不断突破自己的过程中历练出来的。在一个公司里面,经常承担高难度任务的程序员,一定是成长比较快的,薪水增长也一定是比较快的。越是困难的事情,越能体现出个人价值,也越能带给个人成长。

万事起头难,不要害怕困难。事情做不好往往不是因为没有能力,大都是由于缺乏恒心。只要不怕困难,坚持前行,一定会有不一样的收获。

事业就像女人,谁去追求,谁就能得手。金钱也一样。

5. 缺乏责任心

工作上不管什么事儿,反正不是自己的事儿,缺乏责任心,干好干不好都无所谓,对交付承诺、对产品质量都不在意,没什么事儿能让他上心。

一个人的责任心如何,决定着他在工作中的态度,决定着其事业的好坏和成败。如果一个人没有责任心,即使他有再大的能耐,也不一定能做出好的成绩来。

6. 消极,抱怨

工作稍有不顺,就怨气沸腾,这个怎么怎么样,那个怎么怎么样,而我怎么就这样,任务不公平,资源不公平,那谁谁不支持我,那谁谁不配合……

抱怨不能使事情变好,反之,它会让负面情绪蔓延,蚕食你的精力和时间,让你产出更低。成功者永不抱怨,抱怨者永不成功。立刻停止抱怨,早一分钟停止,你就离目标近一分钟。

7. 没有时间管理观念

每个人的一天都只有24小时,人和人的差别就在于如何利用时间上。

有的人每周都有目标,每天都有计划,早上起来会想今天要做的几件重要的事,晚上会回顾今天完成的事,总结干成了什么干坏了什么,还会有计划的学习新知识新技能,这样日积月累不断坚持,每一天都是高效的,每一天都朝着更丰富更完美的自己前进。

而有的人则漫无目的,走哪算哪,到了公司,上午基本做不成事儿,到下午了还不知道要做什么,晚上也发愁如何消磨时间……

8. 为薪水工作

虽然工作的一大目的是获取薪水,养活自己以及供给家庭所需;但是,这只是工作最直接的报偿,同时也是最低级的目标。

如果我们为薪水而工作,将注定我们是短视的,也将注定受到最深的伤害。假如你看不到工资以外的东西,斤斤计较于薪水、福利、职位等,那外界的些微风吹草动就可能让你像浮萍一样飘来荡去,你很快就会失去平衡,失去信心,失去热情,失去平和,进而在工作时总是采取一种应付了事的态度,能少做就少做,能躲避就躲避,觉得只要对得起自己的那份薪水就成了。长此以往,你追求的高薪水反倒得不到。

我们进入一个公司工作,是为了自己,不是薪水也不是别人,比薪水更重要的,是成长和成就自己的机会。我们一定要明白,公司、企业、组织,都是我们锻炼自己、修炼自我的平台,我们不是为薪水工作、不是为老板工作、不是为家人工作,是为实现自我而工作,是为更完美的自己而工作。

唯有志存高远,方能风行天下。

9. 其实不喜欢软件开发

有一部分人从事软件开发工作,并不是因为喜欢,也没有干着干着从不喜欢变成喜欢。他们可能是喜欢软件开发附带的高薪水——平均薪水比其他行业高。人做一件自己不喜欢的事情时,心理上没有亲近感,不会想着怎样把事情做得更好,往往是差不多就成了,不太可能有精益求精积极向上的追求。因为在做不喜欢的事情时,情感上是拒绝的,情绪上是想逃离的,总想着早点儿完事儿拉倒,每一天去单位时不是充满期待,而是各种担忧、烦躁、畏惧,到了单位,稍有困难或不顺心,就会消极、抱怨、抵触、拒绝……

做喜欢的事,能最大可能发挥一个人的潜能和热情,会最快速地通向成功成就自己。而做不喜欢的事,一开始就注定了事倍功半,最后也往往会是痛苦不堪或半途而废。

转载自:

月薪3万的程序员都避开了哪些坑

本文通过一个实例来讲解如何使用 WinDbg 来调试 Windows CriticalSection 死锁的问题。

演示示例

这里有一个关键区锁死问题的程序,运行之后依次点击“CS 锁死”按钮、右上角退出按钮,程序就会卡死。

对于眼下的这个问题,界面完全失去响应,这说明负责消息处理的 UI 线程阻塞了。

对于几乎所有的 windows GUI 程序,编号为 0 的初始线程就是 UI 线程,windows 发现该界面一段时间没有消息响应之后就会在标题后面加上“(未响应)”。

阅读全文 »
0%