TCP协议入门

Java程序员进阶三条必经之路:数据库、虚拟机、异步通信。

前言

想玩转异步通信,不懂TCP协议怎么行?tcpdump目前是最好的命令行抓包工具,所以我选择用它来学习TCP协议。

使用方法

tcpdump -i any -X -nn -s0 -S port <port>

tcpdump的参数巨多无比,我只介绍我所掌握的。

  1. -i any,网络接口,any表示任何接口,也可以监听具体的接口,比如-i eth0。
  2. -X,列出十六进制 (hex) 以及 ASCII 的数据包內容。
  3. -nn,不解析域名或端口。比如21端口是FTP端口,我们希望显示21,而非tcpdump自作聪明的将它显示成FTP。
  4. -s0,不限制捕获的内容大小。
  5. -S,打印绝对序列号,这个参数极其重要,稍后介绍。

三次握手和四次握手

Paste_Image.png

开启本地服务监听1234端口,调用tcpdump命令,最后启动客户端:

telnet localhost 1234

再退出客户端,
日志输出:

16:17:43.121895 IP 127.0.0.1.54024 > 127.0.0.1.1234: Flags [S], seq 947792371, win 43690, options [mss 65495,sackOK,TS val 5673569 ecr 0,nop,wscale 7], length 0
    0x0000:  4510 003c bb92 4000 4006 8117 7f00 0001  E..<..@.@.......
    0x0010:  7f00 0001 d308 04d2 387e 29f3 0000 0000  ........8~).....
    0x0020:  a002 aaaa fe30 0000 0204 ffd7 0402 080a  .....0..........
    0x0030:  0056 9261 0000 0000 0103 0307            .V.a........
16:17:43.121910 IP 127.0.0.1.1234 > 127.0.0.1.54024: Flags [S.], seq 4032343998, ack 947792372, win 43690, options [mss 65495,sackOK,TS val 5673569 ecr 5673569,nop,wscale 7], length 0
    0x0000:  4500 003c 0000 4000 4006 3cba 7f00 0001  E..<..@.@.<.....
    0x0010:  7f00 0001 04d2 d308 f058 afbe 387e 29f4  .........X..8~).
    0x0020:  a012 aaaa fe30 0000 0204 ffd7 0402 080a  .....0..........
    0x0030:  0056 9261 0056 9261 0103 0307            .V.a.V.a....
16:17:43.121920 IP 127.0.0.1.54024 > 127.0.0.1.1234: Flags [.], ack 4032343999, win 342, options [nop,nop,TS val 5673569 ecr 5673569], length 0
    0x0000:  4510 0034 bb93 4000 4006 811e 7f00 0001  E..4..@.@.......
    0x0010:  7f00 0001 d308 04d2 387e 29f4 f058 afbf  ........8~)..X..
    0x0020:  8010 0156 fe28 0000 0101 080a 0056 9261  ...V.(.......V.a
    0x0030:  0056 9261                                .V.a
16:17:47.187398 IP 127.0.0.1.54024 > 127.0.0.1.1234: Flags [F.], seq 947792372, ack 4032343999, win 342, options [nop,nop,TS val 5674585 ecr 5673569], length 0
    0x0000:  4510 0034 bb94 4000 4006 811d 7f00 0001  E..4..@.@.......
    0x0010:  7f00 0001 d308 04d2 387e 29f4 f058 afbf  ........8~)..X..
    0x0020:  8011 0156 fe28 0000 0101 080a 0056 9659  ...V.(.......V.Y
    0x0030:  0056 9261                                .V.a
16:17:47.187736 IP 127.0.0.1.1234 > 127.0.0.1.54024: Flags [F.], seq 4032343999, ack 947792373, win 342, options [nop,nop,TS val 5674585 ecr 5674585], length 0
    0x0000:  4500 0034 3dde 4000 4006 fee3 7f00 0001  E..4=.@.@.......
    0x0010:  7f00 0001 04d2 d308 f058 afbf 387e 29f5  .........X..8~).
    0x0020:  8011 0156 fe28 0000 0101 080a 0056 9659  ...V.(.......V.Y
    0x0030:  0056 9659                                .V.Y
16:17:47.187742 IP 127.0.0.1.54024 > 127.0.0.1.1234: Flags [.], ack 4032344000, win 342, options [nop,nop,TS val 5674585 ecr 5674585], length 0
    0x0000:  4510 0034 bb95 4000 4006 811c 7f00 0001  E..4..@.@.......
    0x0010:  7f00 0001 d308 04d2 387e 29f5 f058 afc0  ........8~)..X..
    0x0020:  8010 0156 fe28 0000 0101 080a 0056 9659  ...V.(.......V.Y
    0x0030:  0056 9659                                .V.Y

对比日志和图片,基本上可以轻松理解三次握手和四次握手的机制,简单补充一些知识。

  1. 四次握手中的第二次和第三次可以合并成一次。
  2. 如果tcpdump命令没有-S选项的话,三次握手中的第三次就会变成ack 0。原因是:tcp在收到第一条数据包之后,后续的数据包,是使用之前数据包的偏移来显示的。
  3. seq是包的序号,用来解决网络包乱序问题。
  4. ack表示确认收到,用来解决不丢包的问题。
  5. flags是包的类型,主要是用于操控TCP的状态机的,有如下几种状态:
  6. S:SYN(同步),开始会话请求。
  7. A:ACK,应答。
  8. F:FIN,结束会话。
  9. R:RST(复位),中断一个连接。
  10. P:PUSH(推送),数据包立即发送。
  11. U:URG,紧急。
  12. E:ECE,显式拥塞提醒回应。
  13. W:CWR,拥塞窗口减少。
  14. .:没有状态。

常见瓶颈

TCP网络应用出问题,十有八九是以下两种情况:

  1. 主动关闭连接方出现大量TIME_WAIT状态。
  2. 被动关闭连接方出现大量CLOSE_WAIT状态

linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,一旦达到句柄数上限,新的请求就无法被处理了,接着应用程序可能返回大量Too Many Open Files异常。
下图告诉你这两种状态是如何产生的:

Paste_Image.png
  1. 主动关闭方在关闭连接后,需要发送ACK,假设ACK丢失了,被动关闭一方会重发它的FIN。主动关闭方必须维持一个有效状态信息(TIMEWAIT状态下维持),以便能够重发ACK。如果主动关闭的socket不维持这种状态而进入CLOSED状态,那么主动关闭的socket在处于CLOSED状态时,接收到FIN后将会响应一个RST。被动关闭一方接收到RST后会认为出错了。这就是为什么socket在关闭后,仍然处于TIME_WAIT状态的第一个原因,因为它要等待以便重发ACK。第二个原因是确保连接复用时没有残存的数据。TCP不允许新连接复用TIME_WAIT状态下的socket。处于TIME_WAIT状态的socket在等待两倍的MSL时间以后,将会转变为CLOSED状态,此时通道内不会存在残存数据。
    应用程序无法解决TIME_WAIT问题,我想了一个甩锅的办法是让客户端断开连接,因为谁主动断开谁面临TIMEWAIT。
  2. CLOSE_WAIT需要重点关注。被动关闭方在发送ACK以后会处于CLOSE_WAIT状态,此时只要调用close方法就会发送FIN包,脱离CLOSE_WAIT状态。

总结

TCP协议过于复杂,属于很重要但是投入产出比并不高的技术领域,netty提供了非常强大、全面的功能以屏蔽协议细节,所以我不打算在协议上耗太多时间。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容