TCP是一个十分复杂的协议,通过前面几篇文章只涉及了TCP协议中一些基本的概念。

虽然说都是一些TCP最基本的概念,但是试验过程中一直在踩坑,例如:TCP flag设置错误,seq、ack号没有计算正确,TCP状态变迁错误等等。

通过Pcap.Net真正实验一下才发现了很多TCP协议中要注意的细节,例如:Ack、Seq号的计算,EthernetLayer、IpV4Layer 、TcpLayer的层层包装,不同TCP flags的含义等等。

TCP中还有很多重要的内容,先做个记录,后面再深入了解。

  • 往返时间测量
  • 滑动窗口
  • 拥塞避免算法
    • 慢启动
    • 快速重传和快速恢复算法

文章索引

动手学习TCP: 环境搭建

动手学习TCP:TCP连接建立与终止

动手学习TCP:客户端状态变迁

动手学习TCP:服务端状态变迁

动手学习TCP:TCP特殊状态

动手学习TCP:数据传输

动手学习TCP:4种定时器

简单总结

下面就对前面几篇文章中涉及到的TCP知识的进行简单的汇总。

TCP首部

  • 在TCP首部中没有源和目标的IP、MAC地址(IP和MAC地址分别是网络层和链路层首部的信息),只有源和目标的端口
  • Sequence Number是包的序号,网络层(IP层)的传输是不可靠的,可能产生包乱序,所以这个需要可以解决网络包乱序的问题
  • Acknowledgement Number用来确认收到数据包的确认序号,为TCP的传输提供了可靠性保证
  • TCP Flags包括了8个bit,通过对这些bit的设置,可以代表不同类型的TCP数据包

TCP连接建立和终止

三次握手

  • 连接建立发起端发送[SYN]包,该端将主动打开(active open)
  • 接收端将发送[SYN, ACK]包,该端将被动打开(passive open),ACK标志表示对收到的[SYN]包的确认
  • 连接建立发起端发送[ACK]包确认[SYN, ACK]包

四次挥手

  • 连接终止端(client)发送[FIN, ACK] 包,关闭client到server方向的数据发送通路
  • server端发送[ACK]包来确认来自client的[FIN, ACK] 包
  • server端发送[FIN, ACK] 包,关闭server到client方向的数据发送通路
  • client端发送[ACK]包来确认来自server的[FIN, ACK] 包,到此TCP连接关闭
TCP状态机

网络上的传输是没有连接的,包括TCP也是一样的。TCP所谓的"连接",其实是在通讯的双方维护一个"连接状态",让它看上去好像有连接一样。

TCP状态机的全部11种状态中:

  • 客户端特有的状态:SYN_SENT、FIN_WAIT_1、FIN_WAIT_2、CLOSING、TIME_WAIT 。
  • 服务端特有的状态:LISTEN、SYN_RCVD、CLOSE_WAIT、LAST_ACK 。
  • 共有的状态:CLOSED、ESTABLISHED

客户端状态变迁

From State

To State

Recv Packet

Send Packet

CLOSED

SYN_SENT

-

[SYN]

SYN_SENT

ESTABLISHED

[SYN, ACK]

[ACK]

ESTABLISHED

FIN_WAIT_1

-

[FIN, ACK]

FIN_WAIT_1

FIN_WAIT_2

[ACK]

-

FIN_WAIT_2

TIME_WAIT

[FIN, ACK]

[ACK]

TIME_WAIT

CLOSED

-

-

服务器状态变迁

From State

To State

Recv Packet

Send Packet

CLOSED

LISTEN

-

-

LISTEN

SYN_RCVD

[SYN]

[SYN, ACK]

SYN_RCVD

ESTABLISHED

[ACK]

-

ESTABLISHED

CLOSE_WAIT

[FIN, ACK]

[ACK]

CLOSE_WAIT

LAST_ACK

-

[FIN, ACK]

LAST_ACK

CLOSED

[ACK]

-

连接建立超时和SYN_RCVD

当服务端收到客户端的TCP连接请求后,会发送[SYN, ACK]包,进入SYN_RCVD状态。如果没有收到客户端的确认,服务器会尝试重传,并保持SYN_RCVD状态一段时间(通常是30秒到2分钟)。

由于服务端的SYN_RCVD状态,就有了SYN Flood攻击。所谓的SYN Flood攻击就是,恶意的客户端给服务端发了一个SYN后,就下线了,通过这种方式来消耗服务器资源。

TIME_WAIT和2MSL

TIME_WAIT状态也称为2MSL(Maximum Segment Lifetime)等待状态,当TCP的一端进入TIME_WAIT状态后,所产生的效果就是该端口在2MSL这段时间中不能被再次使用。

复位报文段

TCP首部的RST位是用于复位的。一般无论合适一个报文端发往相关的连接出现错误,TCP都会发出一个复位报文段。主要使用:

  • 访问不存在的端口的连接请求
  • 异常终止一个连接
最大报文段长度MSS

最大报文段长度表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。

一般,如果没有分段发生,MSS还是越大越好。报文段越大允许每个报文段传送的数据越多,相对IP和TCP首部有更高的网络利用率。当TCP发送一个SYN时,它能将MSS值设置为外出接口的MTU长度减去IP首部和TCP首部长度。对于以太网,MSS值可达1460。如果目的地址为非本地的,MSS值通常默认为536,是否本地主要通过网络号区分。

MTU

以太网和802.3对数据帧的长度都有一个限制,最大值分别是1500和1492个字节。链路层的这个指标称作MTU(注意MTU是链路层的概念),不同类型的网络大多数都有一个上限。

如果网络层(IP层)有一个数据报需要传输,且数据的长度比链路层的 MTU还大,那么网络层(IP层)就要进行分片(fragmentation),把数据报分成若干片,保证每一个分片都小于MTU;目的端的网络层(IP层)会对收到的分片进行重新组装。

TCP的半关闭

TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力,这就是TCP的半关闭。

客户端发送FIN,另一端发送对这个FIN的ACK报文段。当收到半关闭的一端在完成它的数据传送后,才发送FIN关闭这个方向的连接,客户端再对这个FIN确认,这个连接才彻底关闭。

对于每个TCP连接,TCP管理4个不同的定时器

  • 重传定时器使用于当希望收到另一端的确认。
  • 坚持定时器(persist)使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口。
  • 保活定时器(keepalive)可检测到一个空闲连接的另一端何时崩溃或重启。
  • 2MSL定时器测量一个连接处于TIME_WAIT状态的时间。

TCP keepalive和HTTP HTTP Keep-Alive

  • HTTP协议的Keep-Alive意图在于连接复用,防止过多频繁的端连接造成TCP连接资源浪费
  • TCP的keepalive机制在于保活、心跳,检测连接错误

动手学习TCP:总结和索引的更多相关文章

  1. 动手学习TCP:TCP特殊状态

    前面两篇文章介绍了TCP状态变迁,以及通过实验演示了客户端和服务端的正常状态变迁. 下面就来看看TCP状态变迁过程中的几个特殊状态. SYN_RCVD 在TCP连接建立的过程中,当服务端接收到[SYN ...

  2. 动手学习TCP:数据传输

    前面的文章介绍了TCP状态变迁,以及TCP状态变迁图中的一些特殊状态. 本文主要看看TCP数据传输过程中需要了解的一些重要点: MSS(Maximum Segment Size) Seq号和Ack号的 ...

  3. 动手学习TCP:4种定时器

    上一篇中介绍了TCP数据传输中涉及的一些基本知识点.本文让我们看看TCP中的4种定时器. TCP定时器 对于每个TCP连接,TCP管理4个不同的定时器,下面看看对4种定时器的简单介绍. 重传定时器使用 ...

  4. 动手学习TCP:数据传输(转)

    前面的文章介绍了TCP状态变迁,以及TCP状态变迁图中的一些特殊状态. 本文主要看看TCP数据传输过程中需要了解的一些重要点: MSS(Maximum Segment Size) Seq号和Ack号的 ...

  5. 动手学习TCP: 环境搭建

    前一段时间通过Wireshark抓包,定位了一个客户端和服务器之间数据传输的问题.最近就抽空看了看<TCP/IP详解 卷1>中关于TCP的部分,书中用了很多例子展示了TCP/IP协议中的一 ...

  6. 动手学习TCP:TCP连接建立与终止

    TCP是一个面向连接的协议,任何一方在发送数据之前,都必须先在双方之间建立一条连接.所以,本文就主要看看TCP连接的建立和终止. 在开始介绍TCP连接之前,先来看看TCP数据包的首部,首部里面有很多重 ...

  7. 动手学习TCP:客户端状态变迁

    上一篇文章中介绍了TCP连接的建立和终止. 通过实际操作了解到,在TCP协议工作过程中,客户端和服务端都会接收或者发送特定标志的TCP数据包,然后进入不同的状态. 也就是说,TCP协议就是一个包含多种 ...

  8. 动手学习TCP:服务端状态变迁

    上一篇文章介绍了TCP状态机,并且通过实验了解了TCP客户端正常的状态变迁过程. 那么,本篇文章就一起看看TCP服务端的正常状态变迁过程 服务端状态变迁 根据上一篇文章中的TCP状态变迁图,可以得到服 ...

  9. Mysql数据库学习笔记之数据库索引(index)

    什么是索引: SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间. 聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物 ...

随机推荐

  1. linux下使用taskset设置进程cpu绑定不起作用

    自从大规模使用了虚拟化之后,大流量时soft interrupt在某个cpu很高就是个严重的问题,最近一有时间就研究这个问题,如果网卡本身不支持多队列的话,有没有办法缓解这个问题. 一开始使用rps, ...

  2. 当子查询碰上NULL

    情景: 现在有如图两个表,boy和girl,对应着Boy和Girl两个bean,有共同字段id.name,另外boy还有个外键grilfriend(指向girl的id) 现在要查询所有的Boy,如果有 ...

  3. Python multi-thread 多线程 print 如何避免print的结果混乱

    multithread如何写 这是我第一次写multithread,所以就是照着例子学,下面是我用来学的例子 来自于”Automate the boring stuff with Python”的15 ...

  4. Bootstrap源码分析之dropdown

    源码分析: Dropdowns.scss:下拉框模块 Javascripts/bootstrap/dropdown.js:实现下拉框响应 实现功能及原理: 下拉选项卡,默认不能实现显示选中项的功能 原 ...

  5. JS高程1.javascript简介

    1.javaScript诞生于1995年,最开始是为了处理以前由服务器端语言负责的一些诸如验证的操作. 2.一些名词: ECMA:European Computer Manufacturers Ass ...

  6. [js开源组件开发]network异步请求ajax的扩展

    network异步请求ajax的扩展 在日常的应用中,你可能直接调用$.ajax是会有些问题的,比如说用户的重复点击,比如说我只希望它成功提交一次后就不能再提交,比如说我希望有个正在提交的loadin ...

  7. 【iScroll源码学习04】分离IScroll核心

    前言 最近几天我们前前后后基本将iScroll源码学的七七八八了,文章中未涉及的各位就要自己去看了 1. [iScroll源码学习03]iScroll事件机制与滚动条的实现 2. [iScroll源码 ...

  8. OpenGL显示图片

    最近想用C++在windows下实现一个基本的图像查看器功能,目前只想到了使用GDI或OpenGL两种方式.由于实在不想用GDI的API了,就用OpenGL的方式实现了一下基本的显示功能. 用GDAL ...

  9. Tomcat系统部署启动问题分析一例[sudo 启动]

    今天的系统获取新的版本后部署时突然tomcat无法启动,而比较版本的变化内容,也就是几个jsp和js文件的变化,对于web.xml等都没有调整. 这个问题很是奇怪,下面把步骤总结一下,以避免类似的问题 ...

  10. 浅谈被加壳ELF(即android的so文件)的调试

    本文只讨论如何调试被加壳的ELF文件,包括调试中的技巧运用及调试过程中可能遇到的问题的解决方法,不包含如何还原加固的DEX本文将以某加壳程序和某加固为目标. 一.ELF格式简介 ELF全称:Execu ...