2026-05-05 01:34:37
读其他的书知道了《金阁寺》这本书,就找来读了。读完合上最后一页,心里久久不能平静。说这本书是「惊世骇俗」一点也不为过。
书讲述的日本战后年代,一位有口吃的贫穷青年,被患有绝症的父亲送入鹿苑寺成为建系僧人,母亲最大的愿望,就是看到「我」成为住持。书中的「我」痴迷于金阁寺的美。因为在寺里发生的种种违背于「美」的事情(抑或许「我」本身就是这样的一个人?),给「我」带来煎熬的思想斗争。心理的内耗由于无法了解,「我」的老师对此也不做评论,导致「我」越陷越深,沉迷于自己的世界中。想要承认错误却又因为懦弱而无法行动,导致最终的行为是通过犯下更大的错误来祈求得到老师正面的批评,越陷越深,加上母亲对自己的寄托沉重地无法背负,最终犯下被世人唾弃的滔天大罪。
因为年轻与贫穷,能力受限制,无法掌控自己的生活,我对这种处境很有共鸣。我想起来初中的住校生活,一个月有25天都住在学校里,8 个学生生活在15平米的宿舍里面,老师会随意进出宿舍,翻看学生的物品,没有隐私可言。每一个人都被贴上了无法摘掉的标签:来自农村,如果你学习好,那就是人穷志不穷,是大家学习的榜样,如果学习不好,那就是家境贫寒还不知道努力,是耻辱中的耻辱;家里有钱,如果学习好,就是家里有钱但是还要强,如果学习不好,那就是纨绔子弟;长得漂亮,学习好,那就是天生财貌双全,学习不好,那就是心思都用在了打扮上面。总之,老师无法将事情分开单独看待,无法接受一个学习不好只是不努力,学习好是努力,和家境,长相无关。
虽然这是和本书不想关的东西,但是我想,就是处在这种环境中,没有能力做出改变,才愈发想要尽一切可能打破这一切。对于虚伪之人,「我」能做的,就是做出不符合他们预期的事情,不让他们的预期得逞。书中的「我」其实非常软弱,尝试出走,只是遇到警察就被遣送回寺了,花学费去嫖娼也会受到妓女的教育,没有人看得起。最后火烧金阁寺的时候,也是被一连串的事件推动进行的,中间几次打了退堂鼓,如果不是这些机缘巧合,可能最后不会有这样惊天之举,也许就是一事无成的落魄僧人,被寺里赶出来,落得一个流落街头,最终被人遗忘的命运。
生活在自己没有能力掌控生活的环境中,能做的,就只有顺从掌权者的想法,必须要小心翼翼。这和掌权者没有关系,即使权力的座位上是一个好人,迫于权力的不对称,也会带来极大的心理压力。三岛由纪夫把这种压迫感描写的淋漓尽致。如果一步走错,会陷入深深的怀疑中,想要打破这一切,放弃一切。甚至希望事情朝着糟糕的方向发展,因为这样的话,也就不必再抱有希望,可以心安理得地迎接最坏的结果了。
三岛由纪夫的文笔非常好,摘录书中的几段:
在描写口吃的时候,写道:
显而易见,口吃的毛病成了我与外界交流的一道巨大障碍。每当我想说话时,第一个音总是发不准,这第一个音成了我打开外部世界之门的一把钥匙。遗憾的是,这把钥匙从没打开过门上的锁。其他人都可以通过语言自由自在地打开自己与外界之间的这扇大门,而我无论如何努力也做不到。我的钥匙生锈了。
对口吃的人来说,最难受的就是如何发出第一个音,这让人备受煎熬,就如内心有一只小鸟想飞出去,但浑身沾满了黏稠物,只能慌乱无用地扑扇翅膀。好不容易挣脱出来时,已经赶不上对话节奏了。
在我挣扎着扑扇翅膀的时候,门外的世界偶尔会暂停脚步等我赶上,但在我赶上的时候,那个世界已不再是我尽力要赶上的现实世界了。当我费尽全力挣脱并到达外部世界时,才发现这个世界已经瞬间发生改变,完全背离了我的期待……
描写看热闹的人:
看热闹的人在一田之隔观望,后来人越来越多,大家肩挨着肩沉默观看,连头上的月亮好像都被挤小了。
真是一张不可思议的脸,这样的表情在刚被砍倒的树桩上也能看到。尽管色泽还鲜艳,但成长已不再可能,被迫沐浴在本不该沐浴到的阳光和秋风里,暴露在本不该属于自己的世界里。有为子的脸如同那有着美丽木纹的木桩,想拒绝这个世界,却被拖拽到这个世界上,呈现出不可思议的美……
描述金阁寺顶的金铜合金的凤凰:
我还想起屋顶上那只金铜合金的凤凰,这只历经几百年风吹雨打的神秘的金色大鸟,既不报时,也不飞翔,似乎完全忘了自己是鸟儿。但是,如果认为它不在飞,那就错了。别的鸟儿都在空中飞,而它却展开闪亮的翅膀,永远在时间里翱翔。时间如风,掠过它的双翅向后流逝。金凤凰以亘古不变的姿势,双翼高振,怒目含威,尾翼伸展,双腿稳稳站立,翱翔在时间的长河中。
…
临近闭园时好像来了一个旅游团,从金阁方向传来了阵阵喧闹声。围墙外的脚步声和人声虽然吵闹嘈杂,但经春日的夕暮吸收后,并未有尖锐刺耳的感觉,反而显得柔和且饱满。没过一会儿,脚步声如潮水般远远退去,犹如这片土地上来来往往的芸芸众生的足音。我抬头凝视着金阁顶上的金凤凰,此刻,它正沐浴在落日余晖的残红里。
描述自己梯度之后的头:
我刚落发的头上泛着青光,与空气完美贴合。感觉自己脑中所想之事,与外界仅隔了一层薄薄的、敏感且易破的头皮而已,这是一种奇妙且危险的感觉。我仰起光溜溜的头颅凝望金阁,感觉它不仅进入了我的视界,还通过这颗光头渗进了我的体内,与我融为一体,跟我的头一样,在骄阳暴晒下感受到热,而在夕阳西下时又会凉下来。
我在绝望中等待,因为我相信,这澄清的早春晴空就像闪亮的玻璃窗一样,虽然我们看不见,但其背后一定隐藏着强大的火力和毁灭一切的力量。如前所述,我这个人不擅表达对人的关爱,父亲的死及母亲的困窘都没有在我的心里激起一片涟漪。我幻想着某天天空中突然出现一台巨大的碾压机,能将一切灾祸、世界末日和人间惨剧,无论是人还是物,无论是美还是丑,无差别地统统碾碎。那个早春异常灿烂的晴空,似一把可覆盖整个大地的巨大利斧,闪着寒光。我期待那把斧尽快砍下,不给任何人思考的余地。
对于友情的描述:
是的,有时候我甚至觉得,鹤川是一位炼金术大师,他善于从铅里炼出黄金。如果我是照片的底片,鹤川就是照片的正片。我惊讶地发现,很多时候,一旦经他的过滤,我的浑浊不堪的心情不仅瞬间消失殆尽,还会转变成纯净透明、光彩熠熠的感情。当我结结巴巴、踌躇无措时,鹤川就会伸出援手,将我的感情翻转过来展示给外界看。一次次的惊愕让我明白,如果仅停留在感情层面,那么这世上最善和最恶的感情其实并非截然不同的东西,其效果也是相同的。而且,从表面上看,杀意和慈悲心也没什么不同。我想,关于这些,无论我如何费尽口舌地向鹤川说明,他也不会相信吧,但对我来说,这却是一个非常可怕的发现。因为鹤川的存在,让我不再惧怕伪善,但对我来说,伪善只不过是一种相对的罪恶而已。
…
瞥见那一抹青痕时,我顿感不安。眼前的这位少年和我不同,他的生命将在纯洁的末端燃烧,在燃烧之前,未来隐藏不见。未来的灯芯浸在冰冷透明的油里。如果留给未来的只有纯洁和无瑕的话,谁还有必要预测自己的纯洁和无瑕呢?
描写下雪:
究竟顶的大门今天依旧对着天空敞开。仰望它时,我的心却随着雪花飞舞:飘进敞开的大门,在空无一物的究竟顶狭小的空间里飞舞,接着落在墙壁一片生锈的金箔上,失去活力,停止呼吸,最后变成一颗透着金色的露珠。
希望破灭之后的绝望感:
这时,我心里产生了异样的冲动,如同有满腹话语想要表达,却因口吃妨碍而欲说不能,话语一直卡在喉咙里燃烧一样。我想寻求解脱。眼下,不仅是母亲曾经暗示过的继承老师衣钵的希望已然渺茫,就连上大学的希望也已荡然无存。我想从这无声地桎梏着我、重重地挤压着我的窒息感中解脱出来。
…
一种可怕的不满让我们这样的人和这个世界处于对立状态,我们和世界必须有一方肯妥协并做出改变,这种不满才有可能得到治愈。但我讨厌渴望改变的梦想,也讨厌毫无意义的白日梦。但是,我又喜欢在“世界若变化,我就不复存在;我若变化,世界也将烟消云散”这样的问题上刨根问底。这样的确信,反过来倒像我与这个世界的某种和解、某种融合。像我这样肢体有残障的人是不会被世人所爱的,因为我有这样的想法才能得以和这个世界共存。但是,残障人士最容易陷入的陷阱,不是和外部世界的对立状态得以消除,而是全盘接受自己与世界对立的状态。于是,残疾就成了让你和这个世界格格不入的不可调和的存在……
在这个逃课的午后,和煦的春光和阵阵和风就像新做的衬衣,轻柔地触碰着肌肤。
这是因为美可以委身于任何人,但又不专属于任何人。该怎么跟你解释才好呢?对了,美这种东西就像虫牙,它通过与舌头触碰、牵连舌头、引发痛感等宣示自己的存在。最后,人们会因为无法忍受疼痛而请医生将之拔掉。当人们将刚被拔掉的血淋淋的、脏兮兮的、茶垢色的虫牙放在手掌上,一定会说:就是它呀!让我痛苦的就是这小小的东西吗?是它不断对我宣示存在感,让我寝食难安吗?像这样在我身体里顽固存在的东西难道就是这种死掉的物质吗?这个和那个真的是同一种东西吗?这个本应是我身体外部的东西是因何缘由与我的身体内部结合,成了令我痛苦的根源呢?这东西存在的依据是什么呢?而这依据本就存在于我的身体内部吗?或者就是依据它自身呢?不管怎么说,刚从我身上拔下来的这东西绝对不是我身体的一部分,也断然不是那个东西。
总的来说,我的体验中仿佛有一种神秘的巧合在悄然运作,宛如一条挂满镜子的长廊,一个影像无限地延伸到深处。新遇见的事物,清晰地映射出过去所见之物的影子。人最容易被这种相似性所牵引,不知不觉就走到走廊尽头,迈向那深不见底的幽暗深处。命运并非突如其来,它如同一个潜伏的影子,悄无声息地渗透进生活的每个角落。比如,那个日后被判死刑的男人,平日里经过路旁的电线杆或铁道口时,意识中或许时常浮现绞刑架的幻影,甚至对它怀有一种莫名的亲近感。
因此,我的体验中没有堆积物。没有层层堆积的地层,也没有足以堆砌成山峦的厚重积淀。除了金阁,我对世间万物都毫无亲近之感,甚至对自己的体验也未曾有过特别的眷恋。但我深知,在这些体验中,仍有一些尚未被时间之海的黑暗完全吞噬的碎片,以及还没陷入毫无意义的无限重复的部分,这些小部分正在悄然聚拢,逐渐形成卑鄙而不祥的图画。
我经常思索,这些细小的部分又是什么呢?这些闪烁的碎片,甚至比路旁丢弃的啤酒瓶碎片更没有意义,更加杂乱无章。
尽管我如此说,却也不能就此断定这些片段就是那些曾经被塑造成美丽而完整的形态所丢失的碎片。它们因毫无存在意义、缺乏规律而被世人当作丑陋的东西,惨遭抛弃,却仍在各自默默憧憬着未来。以卑微的碎片之身,无所畏惧地、诡异地、静谧地……憧憬着未来!憧憬着那个绝无可能痊愈的、无法企及的、闻所未闻的未来!
…
我非蜜蜂,故不受夏菊诱惑;我非夏菊,故亦不会招来蜜蜂。所有的形态和生之间的融洽已然消逝,世界再度坠入相对性之中,唯有时间永恒流淌。
细节的描写:
这时,背后有人影闪现。阴沉的天空渗出一丝微光,摆放在玄关的鞋柜上的木纹瞬间鲜亮起来。
…
看到了永生的幻象;而具有永恒不灭之美的金阁,却让我感受到一股死亡的气息。为什么鲜有人意识到,其实人类这种寿命有限的生物是无法根绝的,但金阁这样具有不灭之躯的东西却很容易被消灭。
…
那天晚上她留在金刚院里的血,仅像早起开窗时,被惊飞的蝴蝶留在窗框上的磷粉而已。
书中对细节的描写,真实地不像虚构小说,于是读完之后我去查了金阁寺的维基百科:1950年7月2日凌晨(与书中描写的时间相同),京都市消防队收到火警,称鹿苑寺起火。等到消防队到了鹿苑寺的时候舍利殿(俗称金阁)已经燃起熊熊大火,消防队员无法靠近。这起纵火事件中并没有人员伤亡,但是舍利殿被全部烧毁,创建者室町幕府的第三代将军足利义满的木像,观音菩萨像和如来佛祖像以及众多古本佛经被焚毁。
经过事后调查,发现鹿苑寺的见习僧人林承贤在纵火事件后失踪。后来警方在寺院后面的左大文字山发现林承贤已经切腹,蹲坐在地上。经过抢救,林承贤捡回一条性命。但是被判处7年的惩役(坐牢加罚役),最后病死狱中。
在现实生活中同样对他期望很高的妈妈,经警察传唤返家时,从行驶中的山阴本线列车跳下保津峡自杀。

金阁寺在 1955 年开始重建,今日文明世界的鹿苑寺舍利殿,是根据在明治时代翻修时留下的图纸重建的。比重建之前的还要豪华。
《金阁寺》以第一人称书写,其实和作者本人,三岛由纪夫有很多相似的地方。三岛由纪夫也是体弱多病,不过后来为了不被身体的自卑困扰,开始健身,变成了一个肌肉男。
三岛由纪夫其实是一个变态。
三岛对日本传统的武士道精神和严厉的爱国主义深为赞赏,对日本第二次世界大战战败后社会的西化和日本主权受制于美国非常不满。经过长时间的准备,和盾会(也是他创立的)成员,跑到日本陆军基地,绑架了一个中将,发表演说,企图发动政变。
各位好好听一听。静一静,请安静,请听我讲。一个男人正在赌上生命和你们讲话。好吗?这个,现在,各位日本人,如果在这里不站起来的话,自卫队如果不在这里站起来的话,宪法是不可能改变的。各位只会永远的成为区区美国的军队而已啊……。
——三岛由纪夫,于总监部阳台(译)
我已经等了四年了,(等著)自卫队站起来的日子……已经等了四年了,……我再等……最后的三十分钟。各位是武士吧?如果是武士的话,为何要保护“将自己否定”的宪法呢?为何要为了“将各位否定”的宪法,向着“将各位否定”的宪法低头呢?只要这(宪法)还在,各位是永远无法得到救赎的啊!
然而,没有人回应他,甚至嘲笑三岛是一个疯子。
三岛随后从阳台退入室内,按照日本传统仪式切腹自杀。
1999年,在富士山旁边建立了一个三岛由纪夫文学馆,来纪念他。

2026-04-21 12:14:17
「未来两周受季风交替影响,本地多数日子的下午,预计会出现短暂雷阵雨,有几天的最高气温可能达到35摄氏度。未来两周全岛降雨量,预计接近常年平均水平。多数下午,部分地区将出现短暂雷阵雨,有时可能持续至傍晚;也可能有几天降雨不多。」联合早报这么说。最近会下雨已经出现在了新闻上,而不是天气预报上。
春季到了,太阳跑到了赤道的北边。我住的房子朝北,每天起床阳光会射进屋里,晒得玻璃发烫。
高温伴随着雨季,雨水降下来马上又被蒸发,每一天的空气都湿漉漉的。有时候太阳还在天上,没有什么乌云,竟然也下起来雨。
除湿机派上了大用场。每天可以从空气中吸出来两桶水。
说到除湿机,我买的 Novita 牌子,这个公司曾经把自己的产品线全部升级了一遍,从空气净化器到滤水器,所有的型号后面加上了一个 plus——和之前唯一的区别就是必须用他们自己生产的滤芯,售价高昂,而且滤芯到期之后机器会强制停止工作,必须更换。
但是之前非 plus 型号的滤芯还是在售,并且无法在 plus 上使用。用 Shopee 搜出来,非 plus 居然还排在前面,我就上当了,白白浪费了钱,得重新买。
真是气人。
2026-03-17 10:53:03
答案是 MTU 设置错误1,链路可以发送的最大 MTU 小于 1500 bytes,但是客户端侧配置的 MTU 却是 1500 bytes。所以 TCP 连接建立之后的包,无法到达另一端。在等待 3.5s 左右,发送端觉得链路存在问题,尝试降低发出的包的大小,这时候就可以发过去了,链路上才开始数据传输。
要定位这个问题,我们现在抓包文件中,找到传输数据最多的那个 TCP flow,就是传输数据最多的那个。这个连接是我们重点研究的对象。右键选择 Follow > TCP Stream,来只展示这一个会话。(如何追踪某一个 TCP 流,在前面 重新认识 TCP 的握手和挥手2 中也介绍过)。
TCP connection 建立之后,客户端一下发了 10 个包,大小都为 1500 bytes。但是服务端一个都没有 ACK。

然后客户端开始重传。
前 3 次重传分别发生在 0.3s, 0.8s, 1.7s,也都没有收到 ACK。
第 4 次重传发生在 3.5s 这个包不再以 1500 bytes 发送了,而是 1076 bytes (TCP 层是 1024 bytes) 发送。这个包得到了服务端的 ACK。

于是客户端知道,1076 bytes 的包可以被服务端收到,所以后续都用 1076 bytes 作为 MTU 发送。过一段时间之后尝试更大的包,1288 bytes,1394 bytes,发现也没有被 drop,就继续 probe 并且增大 MTU,最后用 1399 bytes,接近链路的真实 MTU (实际链路 MTU 是 1400 bytes)。
这就是每一个连接都会卡 3.5s 的原因。
为什么要重传 3 次才开始降低 MTU 呢?
这是通过 tcp_retries1 设置的。man 是这么说的:
The number of times TCP will attempt to retransmit a packet on an established connection normally, without the extra effort of getting the network layers involved. Once we exceed this number of retransmits, we first have the network layer update the route if possible before each new retransmit. The default is the RFC specified minimum of 3.
即 TCP 会尝试 tcp_retries1 次数的重传,而不涉及 IP (network) layer.
如果超过了 tcp_retries1 还没有重传成功的话,(默认第 4 次)就会认为链路存在异常了,需要 IP 层接入,比如开始 mtu probe 尝试解决问题。
如果设置为 1,那么在卡的时间就会降低到 1s 左右。(当然,最好的解决方式还是设置正确的 MTU)。
# sysctl -w net.ipv4.tcp_retries1=1
net.ipv4.tcp_retries1 = 1
# iperf3 -c 10.0.2.2 -b 10M
Connecting to host 10.0.2.2, port 5201
[ 5] local 10.0.1.2 port 54580 connected to 10.0.2.2 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
[ 5] 1.00-2.00 sec 128 KBytes 1.05 Mbits/sec 22 15.7 KBytes
[ 5] 2.00-3.00 sec 3.50 MBytes 29.4 Mbits/sec 2 150 KBytes
[ 5] 3.00-4.00 sec 1.25 MBytes 10.5 Mbits/sec 0 200 KBytes
[ 5] 4.00-5.00 sec 1.12 MBytes 9.44 Mbits/sec 0 200 KBytes
[ 5] 5.00-6.00 sec 1.25 MBytes 10.5 Mbits/sec 0 200 KBytes
[ 5] 6.00-7.00 sec 1.12 MBytes 9.44 Mbits/sec 0 200 KBytes
[ 5] 7.00-8.00 sec 1.25 MBytes 10.5 Mbits/sec 0 200 KBytes
[ 5] 8.00-9.00 sec 1.12 MBytes 9.44 Mbits/sec 0 200 KBytes
[ 5] 9.00-10.00 sec 1.25 MBytes 10.5 Mbits/sec 0 200 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 12.0 MBytes 10.1 Mbits/sec 26 sender
[ 5] 0.00-10.02 sec 12.0 MBytes 10.0 Mbits/sec receiver
iperf Done.而根据 TCP 的重传时间,大概就是在 3.5s 左右了。
前面说,第 4 次重传的包是从 1076 bytes 开始发送,为什么是这个数字呢?
这个是 sysctl 参数 net.ipv4.tcp_base_mss = 1024 控制的。TCP payload 是 1024 bytes,加上 TCP 的 header,就是 1076 bytes 了。
如果读者尝试复现这个例子,会发现在 MTU 设置错误的情况下,会一直卡住。这是因为 MTU 出现问题的时候,默认的工作机制是靠 ICMP 消息 “Fragmentation Needed” (Type 3, Code 4 in IPv4) 来提示需要降低 MTU 的。但是现实情况中,这个 ICMP 一般是收不到的(因为各种设备为了所谓的「安全问题」丢弃了 ICMP),这样就会出现 blackhole,一直重试缺卡在这里。默认情况下,MTU 错误的设置地大了,是会一直卡住的。
但是可以通过 sysctl 参数设置 net.ipv4.tcp_mtu_probing,默认是 0,即不用 probe。
如果是 1 的话,在出现 blackhole 的时候就会尝试降低 segment 的大小看能不能通。即本文中的情况。
如果是 2,是一直启用,即 TCP 不管对方说的 MSS,发送的时候总是从一个小的 MSS 开始发,如果没有问题,再逐渐加大。
MTU 常见的原因,以及一些其他的相关讨论,可以参考下面列出来的 有关 MTU 和 MSS 的一切 一文。
︎
︎
这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。
如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!
如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。
没有链接的目录还没有写完,敬请期待……
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。
2026-03-12 04:53:31
一天工作日,你拿着刚买的咖啡来到了办公室,准备开始做计划好的工作,度过本该是平平无奇的一天,直到——一位用户发过来消息说他们有新的机器上线之后,所有的 TCP 连接都自带3.5s左右的延迟!他们的服务在使用新的服务器之后,延迟都上升了 3.5s!
经过他们自己的 debug,他们发现,延迟增加之后,在 TCP 连接建立之后,有3.5s 的时间没有发送数据,之后,网络就正常了!然后我们知道,不光服务器是新的,机架,网络设备,都是新的。这批服务器本不该你来负责,但是这个现象也太怪了!所有人都知道你是公司里的网络专家,如果有有解决不了的网络问题,就会来找你。
你让用户用 iperf 测试一下带宽1,用户测试了一下,结果如下:
$ iperf3 -c 10.0.2.2 -b 10M
Connecting to host 10.0.2.2, port 5201
[ 5] local 10.0.1.2 port 45026 connected to 10.0.2.2 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
[ 5] 1.00-2.00 sec 0.00 Bytes 0.00 bits/sec 1 1.41 KBytes
[ 5] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
[ 5] 3.00-4.00 sec 384 KBytes 3.15 Mbits/sec 24 22.4 KBytes
[ 5] 4.00-5.00 sec 5.12 MBytes 43.0 Mbits/sec 0 221 KBytes
[ 5] 5.00-6.00 sec 1.75 MBytes 14.7 Mbits/sec 0 328 KBytes
[ 5] 6.00-7.00 sec 1.12 MBytes 9.44 Mbits/sec 0 328 KBytes
[ 5] 7.00-8.00 sec 1.25 MBytes 10.5 Mbits/sec 0 328 KBytes
[ 5] 8.00-9.00 sec 1.12 MBytes 9.44 Mbits/sec 0 328 KBytes
[ 5] 9.00-10.00 sec 1.25 MBytes 10.5 Mbits/sec 0 328 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 12.0 MBytes 10.1 Mbits/sec 27 sender
[ 5] 0.00-10.02 sec 12.0 MBytes 10.0 Mbits/sec receiver
iperf Done.还真是和用户说的一样!
这必须要抓包一下才知道原因了!用户又做了一次 iperf,并且同时执行 tcpdump 进行抓包,过一会儿,就发来了抓包文件。
你看了一会,然后马上就发现了不对劲的地方……
请分析这个抓包文件,找出固定3.5s延迟的问题在哪里。
这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。
如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!
如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。
没有链接的目录还没有写完,敬请期待……
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。
2026-03-04 23:45:20
在网络抓包系列的最后,再来说一下网络学习的一些经验。毕竟,能通过抓包来解决问题的前提是具备网络协议的知识,不然的话 Wireshark 和 tcpdump 用得再熟练也看不懂抓到的包。
以下是我觉得一些比较好的学习方法,我从中获益良多。
学到了一个新的知识点或者新的协议,可以尝试解释给朋友或者同事听。比如在吃饭的时候,「嘿,你知道吗?TCP 三次握手的第三个包实际上是可以携带数据的!」然后他们会想这个问题,问你「要是有些 Server 不能处理带数据的第三个包怎么办?」这样,你就要重新思考你学的知识,看它是否考虑周全。教是最好的学习方法。如果没有朋友的话,可以考虑写一个博客(像我一样?呵呵)。
认识实际的网络,也可以从公司的网络结构开始。平时总结一下自己的问题,多阅读一些内部的文档。在内部 traceroute 跑一下,看看每一个 hop 都是什么。找时间请网络团队的同事吃饭,然后问他们你的问题。
要学会提问。网络协议的目的一部分是传输数据,更重要的,它需要处理各种异常情况,保证即使出现各种意外,也能尽最大努力工作。所以,我们在学习的时候可以经常问题自己:如果这时候出现 xx 会怎么样呢?
问自己问题,然后思考,尝试给自己解答。在思考的过程中,会产生很多解决方案,大部分可能都是有问题的,然后找到其中的问题,推翻自己的方案。比如,网络为什么要分开三层和二层?这个世界上只有 IP 层,没有链路层行不行?或者只有链路层,不要 IP 层了行不行,整个世界都是一个「大二层」,会有什么问题?
网络相关的知识常常是零碎散乱。我的经验是,不要一开始就跳到兔子洞里面去。面对一个新的概念的时候,可以这样来入门。举个例子说,比如 SOCKS5 协议:
其实我觉得,网络协议的设计在最开始的时候考虑并没有很周全,比如 TCP 的一些问题,HOL Blocking;比如 OSPF 协议的奇怪名字 NSSA 之类的。感觉是设计出来之后,然后发现在现实中会有问题,就会在给原来的东西打上补丁。
很多网络协议设计的是很美的,我喜欢那些简单又能解决问题的协议。比如 VRRP,只有一种数据格式包。像 TCP,DHCP 这种就复杂许多,它们的魅力在于解决了复杂的问题,适应各种复杂的环境。
了解网络协议除了按照上面的方法自己来挑战设计,还可以格物致知,看协议的每一个字段,搞清楚这些字段都在解决什么问题。一般每一个字段都是为了解决某种问题或需求而存在的。
面对复杂的协议的时候,把它拆成一个一个小的部分,单独攻破。比如 BGP,状态,选路之类的太复杂了。方法就是 break down,一个一个来。
光学习 Wireshark 这种工具是不行的,工具是围绕网络协议设计出来的,网络协议设计出来是为了解决真实的问题的。所以学习网络协议,它们解决问题的方法,才是主要的。另外,只有懂网络协议才能用好工具。比如,精通 ICMP 和 IP 的 TTL 设计,才能精通 traceroute 的使用。
像 TCP 的书从协议设计到实现,有数不清的书来介绍。读一本是不够的,因为对于网络协议,不同的作者有不同的理解,有不同的比喻。读书就像和作者聊天一样,和不同的人探讨自己对一个东西的认识,有助于加深理解。
上面通过自己设计协议来理解协议的方式,就是 Computer Networking: A Top-Down Approach2 这本书作者用的,作者用从零开始设计 TCP 的方式来教授为什么 TCP 是今天这个样子的。
同一本书也可以读第二遍,所谓书读百遍,其义自见。
如果一个视频明显是那种中国大学的讲课录屏,基本就没有必要看了。这些视频通常知识和现实脱节,讲的内容很多也在现实中见不到,照本宣科,避重就轻。除了磨灭读者的兴趣,把有趣变成枯燥,就没什么价值了。没有兴趣和热情,就学不好。
说到最后,兴趣是最好的老师,对我来说,根据自己的知识和工具拨开迷雾,解决一个一个的问题,是再有意思不过的了。每个人会在人生的一个时间,发现这个世界不是公平的。但是在计算机的世界里,是很公平的,多花一点时间,多思考一些,就会多一分收获,它与天分无关。技术会过时,自己辛苦习得的技能也可能被 AI 轻而易举取代,但是曾经在学习和进步中体会到的乐趣是真实存在的,那些经验运用到新的技术中也多少是有所帮助的。祝愿读者在自己的领域体会到平静和乐趣。
这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。
如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!
如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。
没有链接的目录还没有写完,敬请期待……
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。
2026-03-01 23:36:24
这是 网络断断续续 一文的答案。
答案是,在同一个子网内,同一个 IP 地址分配到了 2 个不同的设备上。
对于这种时而正常时而异常的「幽灵问题」,在没有思路的时候,可以通过对比的方法来寻找线索。
有的时候 TCP 能够连通,有的时候无法连通。那么正常的 TCP SYN 包和异常的 TCP 包之间肯定是有什么字段是不一样的。当然,也有可能 SYN 包一模一样,问题出在了其他的网络设备上或者 TCP 的另一端。但是既然题目出给读者了,那么问题的根源肯定是隐藏在抓包文件里面。
正常的 TCP 连接可以完成 TCP 的握手和挥手。

异常的 TCP 连接,发出去的 SYN 直接收到了 RST。

通过对比可以发现,两个 SYN 包的 Dst MAC 是不一样的。

如果不通过对比的方法,顺藤摸瓜,可以用下面的思路。
首先,Src IP 和 Dst IP 分别是 10.210.151.187 和 10.210.151.90,很大概率是属于同一个 /24 子网的 IP,不过要想确认的话需要看下服务器的 IP 地址是如何配置的,子网掩码是不是 /24,这点我们从给出的信息无从得知。
假设确实是属于同一个子网,那么 TCP SYN 包不经过网关,直接发给目的地址,二层的 Dst MAC 地址应该是目的 IP 的 MAC 地址。
假设不属于同一个子网,那么 TCP SYN 包经过网关,TCP SYN 包的目的地址应该是路由器的 MAC 地址。
无论是那种情况,正常情况下发送给同一个 Dst IP 的目的 MAC 应该是唯一且稳定的。通过 Conversation 统计可以看出,通讯的 IP 对只有一对,但是 MAC 的确有 2 对,这是不对的。

造成这种现象的原因是,IP 分配重复了,在同一个子网内,同一个 IP 地址 10.210.151.90 被分配给了多个机器。
发送 TCP 包之前,需要知道对应的 Dst IP 地址的 Dst MAC 地址,怎么知道呢?Src 机器会在整个子网内广播 ARP 询问,持有这个 IP 的机器会回复 ARP。现在子网内有两个相同的机器是相同的 IP 地址。这两台机器的 IP 地址一样,MAC 地址不一样。如果我们现在 arping 10.210.151.90 ,会得到如下的回复:
$ arping -c 3 10.210.151.90
ARPING 10.210.151.90
42 bytes from 5a:65:98:0c:82:02 (10.210.151.90): index=0 time=944.055 usec
42 bytes from c2:10:70:f2:ae:ab (10.210.151.90): index=1 time=997.915 usec
42 bytes from 5a:65:98:0c:82:02 (10.210.151.90): index=2 time=13.799 usec
42 bytes from c2:10:70:f2:ae:ab (10.210.151.90): index=3 time=109.388 usec
42 bytes from 5a:65:98:0c:82:02 (10.210.151.90): index=4 time=6.670 usec
42 bytes from c2:10:70:f2:ae:ab (10.210.151.90): index=5 time=48.983 usec
--- 10.210.151.90 statistics ---
3 packets transmitted, 6 packets received, 0% unanswered (3 extra)
rtt min/avg/max/std-dev = 0.007/0.353/0.998/0.438 ms可以看到,我们发出去 3 个询问,却收到 6 个回复。说明每一个询问得到了 2 个答案。(其实,在诊断和验证这个问题的过程中,最快的方式就是用 arping 来测试一下,而不是抓包来分析。但是这里我们主要讨论抓包技术,所以拿来当作一个分析的案例。)
那么 Src 收到两个 ARP 应答,会以哪一个为准呢?答案是以先收到的为准。
$ ip nei show
10.210.151.90 dev h2-eth0 lladdr 5a:65:98:0c:82:02 REACHABLE但是 ARP 请求广播出去,这两个 ARP 应答哪一个先到是无法确定的,有的时候 5a:65:98:0c:82:02 先到,有的时候 c2:10:70:f2:ae:ab 先到,所以发送给 10.210.151.90 的包,有的时候发给了 MAC 地址为 5a:65:98:0c:82:02 的机器,有的时候发送给了 MAC 地址为 c2:10:70:f2:ae:ab 的机器。
补充一点,在实际的问题排查过程中,我们的 TCP 连接测试失败,最好的排查方法就是去对端进行抓包,看一下对端的机器是否收到了 SYN 包。以及在实际的现象中,客户端收到了 Connection refused ,通常意味着收到了 RST 报文(可能来自真实对端,也可能来自其他设备)。我们在对端抓包的过程中会发现即没有收到 SYN,也没有发出 RST,这说明包到别的地方去了。进而,我们可以发现字网内还有一个「李鬼」的问题。
那么,为什么 ping 的测试完全正常呢?
因为 ICMP 是无连接协议,,ping 的 ICMP 协议回复,是由 Kernel 负责的,所以无论 ICMP 包发送到哪一个机器上,由于它们都设置了这个 IP 地址,所以都可以做出回复。其实抓包中的回复是来自不同的机器,只不过 ping 不知道,只要是收到了回复,就认为一切正常。

最后一个问题,为什么会有 IP 重复的问题呢?
DHCP 可以用来动态分配 IP 地址给设备,但是一般只用于客户端,比如办公网、家用网络中的终端设备,这些设备一般作为连接的发起方,不需要 listen 一个固定的 IP 地址,IP 地址的动态变化对它们影响不大。但是在 IDC 的网络中,每一个服务器的软件都需要固定的 IP 地址,一般不用 DHCP 来动态分配,而是用中心化的 IPAM 系统1追踪 IP 地址的分配情况。如果里面记录的地址不正确,比如,一个地址已经在使用中了,但是并没有在 IPAM 记录,就造成 IP 地址重复的问题。
这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。
如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!
如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。
没有链接的目录还没有写完,敬请期待……
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。