TCP/IP协议实现了不同主机,不同操作系统之间信息交流。由4层构成,从上往下依次为:

1、应用层,包括http,ftp等协议,用于实现某一项具体的功能。

2、传输层,包括TCP和UDP,一个可靠,一个快速。

3、网络层,IP协议,完成IP数据包在网络中的传输,但不可靠。

4、数据链路层,主要用于接收和发送IP数据包。

在网络编程中主要接触TCP,UDP协议。这里对TCP的有关知识做一下小结:

TCP是面向连接的,可靠的传输协议:通过3次握手建立连接,4次挥手断开连接,通过重传机制实现可靠性,此外,通过滑动窗口实现流量控制,还通过一些算法避免网络拥塞。

首先,复习一下TCP头格式:

  • TCP连接用四元组表示一个TCP连接:Sre_IP,Sre_port,Des_IP,Des_port;其中Sre_IP和Des_IP在IP协议头中。
  • Sequence Number是包中字节的序列号,防止网络包乱序。Acknowledgement Number确认已收到的连续最大序列号。
  • Window就是滑动窗口,用于流量控制。
  • TCP Flags:
    • U   Urgent
    • A   Ack
    • P   Push
    • R   Reset
    • S   Syn
    • F   Fin

  一、TCP的状态机

1、TCP的连接和断开伴随着客户端和服务器端的状态变化:

  服务器端主动监听一个端口进入LISTEN状态;客户端发送Syn包进入SYN SEND状态;服务器端收到Syn包,发送Syn包及Ack进入SYN RECEIVED状态;客户端收到服务器的Syn+Ack包,返回一个Ack进入ESTABLISHED状态;服务器端收到Ack后也进入ESTABLISHED状态。三次握手过程中,SYN SEND和SYN RECEIVE状态很短暂,很难捕捉。大部分看到的是LISTEN和ESTABLISHED状态

  客户端发送Fin包,主动断开连接,进入FIN_WAIT_1状态;服务器端收到Fin,返回一个Ack包进入CLOSE_WAIT状态;客户端收到Ack包,进入FIN_WAIT_2状态;至此,TCP连接进入了半连接状态,即客户端已经主动关闭连接,不在发送数据,但是服务器端仍然可以向客户端发送数据。服务器端在应用层要做出判断,如果没有数据要发送了就会执行断开连接操作(调用close)。服务器端发送Fin包,进入LAST_ACK状态;客户端收到Fin,回Ack进入TIME_TAIT状态;服务器端收到Ack,进入CLOSED状态;客户端的TIME_WAIT状态时间到了后,也进入CLOSED状态。服务器端和客户端都可能主动断开连接(其实,连接建立以后就不区分客户端和服务器端了),不过大多是客户端主动断开。

2、三次握手:主要是为了初始化Sequency Number的初始值,作为通信的初始序列号。而初始值是根据一个假时钟赋值的,没必要深究。

3、四次挥手:因为TCP连接时全双工,所以两端都要发送一个Fin包,收到一个Ack包。TIME_WAIT状态持续的时间是2倍的MSL,MSL表示TCP报文在网络最长的存活时间,linux设置为30s。在TIME_WAIT状态时,TCP连接不会接受任何TCP报文,除了Fin报文,并且端口也不能给别的TCP连接使用。原因 一)防止最后一个ACK报文丢失,如果丢失,对方会再发送一次Fin。二)防止该端口被重用,上一个连接迟到的数据包和新连接的数据包混淆。

4、同时连接和同时关闭:一)同时连接发生的概率很小,而且还有点不可思议。我向你发起连接,你不监听也就罢了,居然还要和我连接,而且你要连接的端口正好是我用来和你连接的端口。不管怎么说,TCP支持这种情况,同时连接时双方几乎同时发出Syn进入SYN SEND状态,收到对方的Syn报文会从SYN SEND状态变成SYN RECEIVED状态,收到自己Syn的Ack后进入ESTABLISHED状态。二) 同时关闭的概率还是挺大的,双方同时发出Fin,进入FIN_WAIT_1状态;收到对方的Fin,进入CLOSING状态;收到自己Fin的Ack进入TIME_WAIT状态。

二、重传机制

1、双方建立连接时,互通了Seq Num,然后开始通信。发送端向接收端发送TCP报文,接收端根据接收到的报文的Seq Num回Ack包,Ack是已经收到的连续字节最大序号的下一个序号。如果发送的某一个报文丢失了,发送端要重传该报文,比如:发送端发送了序号为1、2、3、4、5的TCP包,接收端收到了1、2、4、5。所以,接收方只回2的ack。

  • 超时重传

  发送一个报文就启动一个超时定时器,当timeout到了时,3的ack还没回来,就重发。可能只重发3,也可能重发3,4,5.这要看具体实现。第一种慢,但省带宽;第二种快,但浪费带宽,还可能做无用功。但都是基于超时重传。

  • 快速重传

  不以时间驱动,而是以数据驱动。当发送方收到3个重复的确认就会重发相应的数据包。比如,当2到达时,发送方会收到2数据包的确认;4,5到达时,发送方还是收到2的确认,这时发送方会重传数据包3或重传3,4,5……(因为可能6,7到了呢).

  • SACK法

  就是在回复的ack头里添加一个Sack的东西,里面有接收方已经收到数据的情况,防止发送方重传不必要的数据。但是接收方也可能把已经接收到的数据扔掉(让出内存给别的进程),这回导致发送方的sack数据不准,所以,发送方不能完全依赖sack,还要依赖timeout。

  2、timeout的设置:

  基本的方法是取样RTT,然后进过一些公式的计算,得出timeout的值。

  三、流量控制

  1、滑动窗口是实现网络流量控制的一项技术,接收方通过告知发送方自己可用缓存区的大小来限制发送方数据的发送。下面是TCP发送缓存区和接受缓存区的数据结构:

  • 接收端,LastByteRead是应用层上次读的位置,NextByteExpected是上次Ack的位置,LastByteRcvd是收到包的最后一个位置,中间还有一些没收到。
  • 发送方,LastByteAcked是上次确认的位置,LastByteSend是已经发送出去的最后一个位置,LastByteWritten是应用层写到的位置。
  • Window = MaxRcvBuff - LastByteRcvd - 1

2、Zero Window

  当接收方的window为0时,发送方不能再发数据。过一段时间(一般为30s-60s),发送方会发一个ZWP包,让接收方ack,以获取新的window大小。如果3次都为0,有的TCP实现会发送reset断开连接。

3、silly window Syndrome

糊涂窗口综合症,window给的值太小,导致TCP报文携带的数据太少,浪费带宽。解决方法:一)接收端的可用缓冲区如果小于某值 (视具体实现定)就回window的大小为0,等可用的接收缓冲区变大后再通知发送方。二)发送方执行Nagle算法:windows size > MSS或者等待时间超过200ms就发数据。

四、拥塞处理

通过滑动窗口做流量控制还不够,因为数据在中间的传输过程没发控制。数据在传输过程中可能会发生网络拥塞,所以还需要拥塞处理相关的流量控制。

拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生时的快速重传,4)快速恢复

TCP小结的更多相关文章

  1. Java TCP小结

    服务端:                                                                                 客户端: ServerSock ...

  2. tcp、http 学习小结

    tcp.http 学习小结 前言 最近因为cdn的一个问题,困扰了自己好久.因为需要统计网站访问的成功数,而且要求比较精确.目前的实现不能满足要求,因为没有区别访问成功与否,也没有对超时做处理.期间解 ...

  3. 【计算机网络】TCP基础知识详解

    1. TCP概念相关 [!NOTE] TCP(Transmission Control Protocol),又叫传输控制协议. TCP协议是面向连接的,可靠的,基于字节流的传输协议.在基于 TCP 进 ...

  4. nodejs学习笔记之网络编程

    了解一下OSI七层模型   OSI层 功能 TCP/IP协议 应用层 文件传输,电子邮件,文件服务,虚拟终端  TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层 数据格式化 ...

  5. TCP/IP协议头部结构体(网摘小结)(转)

    源:TCP/IP协议头部结构体(网摘小结) TCP/IP协议头部结构体(转) 网络协议结构体定义 // i386 is little_endian. #ifndef LITTLE_ENDIAN #de ...

  6. TCP与UDP区别小结

    TCP(Transmission Control Protocol):传输控制协议 UDP(User Datagram Protocol):用户数据报协议       主要从连接性(Connectiv ...

  7. 【TCP/IP详解 卷一:协议】TCP的小结

    前言:TCP学习的综述 在学习TCP/IP协议的大头:TCP协议 的过程中,遇到了很多机制和知识点,详解中更是用了足足8章的内容介绍它. TCP协议作为 应用层 和 网络层 中间的 传输层协议,既要为 ...

  8. TCP的数据传输小结

    TCP的交互数据流 交互式输入 通常每一个交互按键都会产生一个数据分组,也就是说,每次从客户传到服务器的是一个字节的按键(而不是每次一行) 经受时延的确认 通常TCP在接受到数据时并不立即发送ACK: ...

  9. TCP服务和首部知识点小结

    服务 应用程序会被TCP分割成数据段,而UDP不分割. TCP有超时重传和确认 如果检验和出错将丢弃 IP数据包可能会失序或者重复,所以TCP会处理 滑动窗口来进行流量控制 对字节流的内容不做任何解释 ...

随机推荐

  1. centos 安装cacti监控

    CentOS 6下Cacti搭建文档 安装依赖关系 yum -y install mysql-devel httpd php php-pdo php-snmp php-mysql lm_sensors ...

  2. Anaconda 安装概要

    Anaconda 作为开源项目,集成了Python的大部分第三方包,如:pandas,Numpy,scipy等. 1. 下载地址:https://www.continuum.io/downloads ...

  3. 1.3 ODPS

    来源(完全照搬.仅做记录):http://blog.itpub.net/26613085/viewspace-1327313/ 注册odps账号注册地址:http://www.aliyun.com/p ...

  4. C++线程安全的单例模式

    1.在GCC4.0之后的环境下: #include <iostream> using namespace std;template <typename T>class Sing ...

  5. jenkins自动部署war包到jetty

    1.把jenkins.war包复制到jetty的webapps下面 2.在jetty的webapps下面新建jenkins.xml文件 内容如下: <?xml version="1.0 ...

  6. Spring-MVC填坑之旅-返回json数据

    本文是自己开发中所遇到的问题,对一些及百度到的解决方案做一个记录. DispatcherServlet配置文件 <!-- 定义跳转的文件的前后缀 ,视图模式配置--> <bean i ...

  7. 用VulApps快速搭建各种漏洞环境

    项目主页 https://github.com/Medicean/VulApps 项目介绍 收集各种漏洞环境,统一采用 Dockerfile 形式.DockerHub 在线镜像地址 获取并使用相关镜像 ...

  8. 《JS权威指南学习总结--第九章 类和模板》

    内容要点: 一. 1.第六章详细介绍了JS对象,每个JS对象都是一个属性集合,相互之间没有任何联系.在JS中也可以定义对象的类,让每个对象都共享某些属性,这种"共享"的特性是非常有 ...

  9. CSS3秘笈复习:第七章

    1.边距冲突: 当元素的bottom margin碰到另一个元素的top margin可能会产生一些怪异的计算,浏览器会忽略小的那个值而使用大的值. 2.边距折叠: 假设要在警告框里插入一个标题,并且 ...

  10. 【Python】@property的用法

    设想我们要给一个student()类的一个实例s,添加一个score的属性,比如: s.score=999999 这个值明显是不合理的,但是它却是可行的,怎么能改变这种情况?我们能想到的就是用类方法 ...