TCP与UDP挖掘机(一)初识

面试官偶尔会问到TCP相关的知识点,在最早之前我是一脸懵逼答非所问的,故整理了一下关于TCP的相关知识点,希望对大家有所收获!

为了更进一步了解网络层面的知识,先晒出一张网络体系结构图,加深理解

计算机网络体系结构图

all.png

TCP UDP的区别

TCP UDP
面向连接的协议。基于这种连接方式, 通信设备应在传输数据前建立连接,并应在传输数据后关闭连接 面向数据报的协议。意味着打开、维护、终止连接不会有开销。UDP对于广播和多播类型的网络传输是有效的
点对点通信,连接两端的socket
面向字节流。TCP把传输的各种数据当做无结构的字节流来用
可靠性。它能够保证向目标路由器的数据传输 不可靠性。不能保证向目的地传送数据
错误检测机制。TCP提供了广泛的错误检查机制,这是因为它提供流量控制和数据确认。 UDP只有使用校验和的基本错误检查机制
数据排序。数据包能够按照顺序到达接收器 没有数据排序。若有需求,则需要再应用程序层进行管理
速度较慢。相对UDP而言速度较慢。 快、简单、高效
重传机制。支持重传丢失的数据包 无重传机制
标头大小为20个字节 标头大小为8个字节
重量级 轻量级
用于HTTP,HTTP,FTP,SMTP和Telnet 用于DNS,DHCP,TFTP,SNMP,RIP和VoIP

注:本文所指的Client 均为发送方,Server为接收方

TCP 三次握手、四次挥手

三次握手

建立一个TCP连接时,需要Client和Server总共发送3个包。

三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。

3-way-handshake_1.jpg
  • Step 1(SYN).

    Client 端要和Server端 建立连接,所以要发一个SYN(即同步序列号)的包,初始序号x,保存在包头的序列号(Sequence Number)字段里,指明打算连接的Service port,。

    用于告知Server:我(Client)可能要与你开始通讯了,现在发给你一个我(Client)启动段的序列号。

    此时Client进入SYN_SEND状态

  • Step 2(SYN+ACK).
    Server 端 接收到数据包(通知)后

    使用一个SYN-ACK信号位设置,来响应Client 端的请求。

    即发送了自己的序列号(SVN),初始序号为y,和确认号(ACK,即Client发来的序列号递增1, 即x + 1)。

    此时Server进入 SYN_RCVD 状态

  • Step 3(ACK).

    Client接收到Server端的响应后

    发送确认包(ACK,即Server 发来的序列号递增1, 即y + 1)来确认收到响应,此时Client 进入 ESTABLISHED 状态,当Server 接收到该ACK包后,也进入 ESTABLISHED 状态。

四次挥手

TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake)。

需要四个包的原因是是因为TCP的半关闭引起的

客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。

下面假设Client主动发起挥手动作

4-way-connect-termination.jpg
  • Step 1(FIN).

    Client 端(发起方)要关闭TCP连接,所以要发一个FIN包,序号为x

    发送完毕后,此时Client进入 FIN_WAIT_1 状态(此时表明无数据可发送,但仍可接受数据)

  • Step 2(ACK).

    当Server 端 接收到FIN包后,立即向Client发送确认包(即Client发来的FIN包的序号递增1,x + 1)。

    发送完毕后,此时Server 进入 CLOSE_WAIT 状态(此时表明接收到了Client的关闭,但还没做好“思想准备“关闭连接)

    当Client 端 接收到ACK包后,进入 FIN_WAIT_2 状态

  • Step 3(FIN).

    Server 端 发送ACK包一段时间(这段时间它有一些关闭过程)后,开始发送FIN包,序号为y

    发送完毕后,此时Server 进入 LAST_ACK 状态

  • Step 4(ACK).

    当Client 端 接收到FIN包,即关闭请求后,发送一个确认包(即Server发来的FIN包的序号递增1,y + 1

    发送完毕后,此时Client 进入 TIME_WAIT 状态,目的在于在时间周期n内,允许Client 在发送的ACK包丢失的情况下重新发

    当Server 端接收到ACK包后,连接正式关闭,此时Server进入 CLOSED 状态。Client资源(包括端口号、缓冲区数据)都被释放

    当Client在时间周期n结束后,仍没收到Server 发的ACK包,则认为已正常关闭连接,此时Client 也进入 CLOSE 状态

TCP协议如何保证可靠传输

从上面的体系图可以看到,TCP(即运输层)的报文信息最终会交付到网际层。而网际层不会提供可靠的服务。所以还是要TCP来保证可靠的传输,才能最终保证数据服务的可靠

原理

​ 宏观上看,从TCP的特性可以得知,它有自己的错误检测机制、数据按序传输、确认应答+序列号、支持重传的功能。然后具体的内部处理是怎样的呢?主要有以下两点

  • 停止等待协议

    这是最简单的保证可靠传输的协议

    以下会发生两种情况

    • 无差错

      停止等待协助-无差错.jpg

    可以看到Client 在发送分组M1(即数据单元)后,暂停,等到Server发回确认后,继续发送下一个分组...

    这是理想条件下的无差错情况

    • 有差错

      停止等待协助-超时重传.jpg

当Client 发送 分组M1(会先设置一个计时器,在此计时器内M1仍存在,以便重传)时,可能会遇到数据无法到达Server,或者Server 检测出问题并丢弃了它,在指定时间内Client 如果未收到来自Server 的确认,则会重传M1,即人们常说的超时重传

超时重传会有以下情况

  • 确认丢失(发回延迟)

    Client发送分组M1,Server收到M1并发送确认分组,而在指定的时间内Client没有收到确认,后会重传M1.

    而由于Server 已经收到过M1了, 所以此时它需要 丢弃M1分组, 发送确认分组

  • 确认迟到(发送延迟)

    由于网络延迟等原因,Client发送的分组M1,在指定时间后才到Server, 此时Client 还没来得及收到确认,再次发送分组M1

    而由于Server 刚好收到了M1,所以此时它需要 丢弃M1分组, 发送确认分组

    Client 收到>=2个以上的确认,会执行丢弃操作,并且停止发送

  • 连续ARQ协议

    由于停止等待协议对信道的利用率太低,故可以采用流水线的方式来传输,即连续ARQ协议。

    这里需要提到一个发送窗口的概念。发送窗口支持滑动,所以也有滑动窗口这么一个概念

    ​ Client 会维护一个发送窗口,一个窗口内可以有多个连续分组进行发送,而不必等待对方的确认一条条分组发。

    ​ Server 亦不会对每个分组进行回传确认,而是在按需发送到达的最后一个分组到达之后,发送确认,代表这个窗口的分组已经发送成功

具体实现

1. 使用滑动窗口

​ 窗口主要分为接收窗口和发送窗口

  • 接收窗口

    接收窗口.png

“接收窗口”大小取决于应用(比如说tomcat:8080端口的监听进程)、系统、硬件的限制。图中,接收窗口是31~50,大小为20。

在接收窗口中,黑色的表示已收到的数据,白色的表示未收到的数据。

当收到窗口左边的数据,如27,则丢弃,因为这部分已经交付给主机;

当收到窗口右边的数据,如52,则丢弃,因为还没轮到它;

当收到已收到的窗口中的数据,如32,丢弃;

当收到未收到的窗口中的数据,如35,缓存在窗口中。

  • 发送窗口

发送窗口.png

​ 发送窗口的大小swnd=min(rwnd,cwnd)。rwnd是接收窗口,cwnd用于拥塞控制,暂时可以理解swnd= rwnd =20。

图中分为四个区段,其中P1到P3是发送窗口。

tips:发送窗口以字节为单位。为了方便画图,图中展示得像以报文为单位一样。但这不影响理解。

2. 重传与确认

  • 确认

    这里主要是通过累计确认的方式

  • 重传

    这里主要是上面说的超时重传,每一个报文都会有超时计数器,当超过指定时间后,Client(发送方)会触发重传报文

3. 流量控制(基于滑动窗口)

​ 流量即发送方发送的报文流量。当接收方来不及处理数据时,通过滑动窗口,告诉发送方能够接受的单位字节是多少,以降低发送的频率,防止包丢失

流量控制.png
  • 在建立连接时,接收方(B),告诉了发送方(A):我的接收窗口是400(单位字节).

  • 图中的ACK为TCP首部的ACK字段,ack为首部的确认号字段.

  • 流量控制体现在:rwnd=300, rwnd=100, rwnd=0.在确认报文的窗口字段设定了发送方能够发出的数据多少,从而控制流量.注意只有到首部的ACK字段值为1,窗口字段的值才有效.

  • 假设在B发送了rwnd=0之后,过段时间由于自己又希望接收到数据,于是发出rwnd=400的报文,但是该报文丢失了,这样A依然无法发送数据,B希望接收但接收不到数据.

​ 为解决该问题,TCP为每个链接都设有一个持续计时器.只要接收到对方窗口为0的通知,就启动持续计时器.在计时器到期后,就发送探测报文,对方可以在该报文的确认中告知当前的窗口值.若窗口任然为0,那么就重新设定计时器,若不为0,那么上述的问题就解决了.

4. 拥塞控制

​ 拥塞是指对网络某一资源(带宽,缓存等)的需求超过了可提供的部分,从而使网络中传送的数据不能按时到达,网络性能变差的情况.

拥塞控制就是防止过多的数据注入到网络中,这样网络中的资源压力就小了.

流量控制和拥塞控制似乎很相似,但是他们不同.前者立足于接收和发送者双方的情况;而后者注重的是数据量对网络环境的影响

TCP 粘包、拆包

由于TCP 是一个面向字节流的协议,这也决定了它的数据是无结构的。所以TCP无法得知应用层对于这快数据的定义,而是基于自身缓冲区的实际情况进行数据包的拆分,或者将多个数据包进行合并来发送。

参考下图,在不同的条件下,会发生多种现象

  • Server 分别接收P1,P2,没有发生粘包、拆包
  • Server 一次接收P1+P2两个报文,发生了粘包
  • Server 先接收P2, 再分别接收了P1_1, P1_2,发生了拆包
  • Server 先接收了P2+P1_2,再接收了P1_1,发生了粘包、拆包
  • 另一种极端情况,当窗口非常小,恰逢P1又很大时,可能会发生多次对P1进行拆包
粘包与拆包.jpg

首先我们要知道,发送的数据会先传入发送缓冲区,再通过网络传输发送到接收端的缓冲区

以上现象发生的原因主要是

  • 发送的字节 大于 TCP发送缓冲区的大小,会发生拆包
  • 发送的报文 大于 MSS(最大报文长度),会发生拆包
  • 发送的字节 小于 TCP发送缓冲区的大小,会将多次写入缓冲区的报文一并发送,即发生粘包

解决方案,需要上层应用程序做对应的处理

  • 规定报文长度。例如设定每条报文固定长度为200字节,当不够时,用空格填充
  • 报文末尾添加回车换行符。例如FTP协议
  • 将报文分为header and body,在头部中声明报文长度,然后根据这个长度来获取报文

我们常用的Netty 已经帮我们处理好这些问题,我们仅需调用特定的方法即可。这个在后续的Netty挖掘机系列文章会提到栗子。

比如有:

  • LineBasedFrameDecoder 基于换行符解决
  • DelimiterBasedFrameDecoder 基于分隔符解决
  • FixedLengthFrameDecoder 指定长度解决

参考链接:【读】这一次,让我们再深入一点 - TCP协议

参考链接:什么是 TCP 拆、粘包?如何解决?

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

推荐阅读更多精彩内容

  • 如果对网络工程基础不牢,建议通读《细说OSI七层协议模型及OSI参考模型中的数据封装过程?》 下面就是TCP/IP...
    zhoulujun阅读 3,161评论 1 10
  • 运输层协议概述 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是...
    srtianxia阅读 2,326评论 0 2
  • 端口与进程 TCP 的包是不包含 IP 地址信息的,那是 IP 层上的事,但是有源端口和目的端口。 就是说,端口这...
    XLsn0w阅读 686评论 2 4
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,019评论 0 8
  • 前几天,一个朋友跟我说:你的背影好沧桑。我当时不以为然,现在感触颇深,回想起来好像有那么一丝对与不对的见解。对:月...
    陶仕冶阅读 194评论 2 3