TCP 实际应用

浅谈 TCP 介绍了 TCP 基础的理论知识,这篇主要介绍 TCP 的一些应用场景,主要包括(SYN Flood,TCP 长连接和短连接,TCP/IP 实现)。

1. SYN Flood

SYN Flood 又称 SYN 洪水,是利用 TCP 三次握手的漏洞产生的一种攻击方式。
常用攻击方式有两种,最终结果都是造成服务端在等待 ACK。一种是客户端只管发出 SYN,不理会服务端返回的 ACK。一种是客户端构造错误的来源 IP,使服务端返回 ACK 到错误 IP。这两种情况都会导致服务端无法正常收到客户端发来的 ACK。使得 TCP 连接保持在半打开状态,当 SYN 请求量过大时,会出现大量半打开状态的 TCP 连接,当系统资源被消耗尽后,导致新的连接无法被创建,造成正常用户无法访问。

2. TCP 长连接/TCP 短连接

首先需要知道的是 TCP 连接建立需要三次握手,断开连接需要四次,所以每次 TCP 的建立和关闭是需要消耗资源的。
TCP 短连接就是请求完成后关闭连接(一般是客户端主动关闭)。
TCP 长连接是请求完成后仍保持 TCP 连接的状态,可继续传输数据。TCP 保活功能采用定时器来检测连接状态。客户端可能正常运行,已经崩溃,重启或不可达,服务端需要针对检测的情况做出不同反应。

2.1 优缺点:

短连接管理简单,存在的连接都是最近建立和使用的。但每次建立和关闭新连接会有资源消耗,当在大并发请求场景中使用,会出现大量的 TIME_WAIT 状态的连接。导致资源的较大消耗。
长连接需要 TCP 保活定时器来检测连接状态。同时需要考虑不同长连接的负载均衡问题,但是可以在客户端通过连接池得到部分解决,但在不同客户端之间的负载均衡就无法做到。另外因为长连接存在只创建不关闭的情况,所以会导致建立的长连接越来越多。

2.2 短连接在请求量较大时,导致过多的 TIME_WAIT

参考 浅谈 TCP 1.3 中的图,因为 TCP 是双工模式,所以每个方向的连接都需要单独关闭。
主动关闭的一方发送 FIN 后,收到被动关闭一方的 FIN,随后返回 ACK 信号,被动关闭一方完成关闭连接闭环,到达 CLOSED 状态。
而主动关闭一方收到 FIN 后,发出 ACK,挥手已经结束,所以主动关闭一方不清楚被动关闭一方收到 ACK 没有,所以只能等待超出 2MSL(Maximum Segment Lifetime 报文段最大生存时间)后,如没有再次收到 FIN (重连)即可进行关闭。
2MSL 是因为被动关闭一方首先等待 MSL 如果没收到 ACK 则重新发送 FIN,然后主动关闭一方等待 MSL 看是否能收到被动关闭一方重新发送的 FIN,如果没有收到则表示被动关闭一方已成功收到了 ACK。

3. RPC 接口过度担心性能

例如提供:get_topic_token_by_id 还是 get_topic_by_id?
当数据传输长度小于 MSS,数据仍被封装在一个数据包中进行传输,所以不会导致性能的下降。

4. Socket 剖析

4.1 基础 API

socket():创建一个 socket 描述符(socket descriptor)。
bind():将一个地址族中的特定地址与 socket 进行绑定。
listen():服务器通过 listen 来监听请求。
connect():客户端通过 connect 发出连接请求。
accept():内核生成一个全新的描述符,代表与客户唯一的 TCP 连接。
read()/write():从文件描述符中读取数据或写入数据到文件描述符。
close():关闭 socket 描述符(TODO:accept() 和 socket() 创建的描述符都需要关闭吗?)

4.2 blocking 和 non-blocking 区别?

在 Network IO 操作中会涉及到两种系统对象,一个是调用这个 IO 用户进程(user process),一个是系统内核(kernel)。

4.2.1 写阻塞:

当调用 write 操作时,只是将要写的数据复制到 kernel 的发送缓冲区,什么时候发送到网络,什么时候对方接受,系统不进行通知和保证。所以当 kernel 的 send buffer 满了之后就会造成 write 阻塞,即写入的速度大于对方读取的速度。

4.2.2 读阻塞:

当调用 read 操作时,会首先检查 kernel 的 receive buffer 中是否有数据,如果有数据则将数据拷贝到用户进程中,如果没有数据,blocking 和 non-blocking 进行会做出不同的反应。

4.2.3 blocking vs non-blocking

blocking IO 发现 kernel 中无数据,会进行等待直到有数据出现,然后再将数据从 kernel 拷贝到用户进程。
non-blocking IO 发现 kernel 中无数据会直接返回 error。从用户角度,进程不再需要等待,每次 read 操作都会得到一个结果。当进程发现 read 返回 error 后可以再次进行 read 操作。
关于 blocking IO/non-blocking IO 的详细细节可以参考:IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

疑问:(TODO)
长连接导致报错的原因?(TCP keepalive)
当 TCP 数据包被 socket 隔断后如何重新组装?(eg: return big_data)
当 Socket 读写发生错误时,如何进行数据重传?

参考资料:

SYN flood - 维基百科
TCP的 TIME_WAIT 快速回收与重用
Socket 通信原理和实现
IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
TCP/IP 应用程序的通信连接模式

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

推荐阅读更多精彩内容