TCP小结
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小结的更多相关文章
- Java TCP小结
服务端: 客户端: ServerSock ...
- tcp、http 学习小结
tcp.http 学习小结 前言 最近因为cdn的一个问题,困扰了自己好久.因为需要统计网站访问的成功数,而且要求比较精确.目前的实现不能满足要求,因为没有区别访问成功与否,也没有对超时做处理.期间解 ...
- 【计算机网络】TCP基础知识详解
1. TCP概念相关 [!NOTE] TCP(Transmission Control Protocol),又叫传输控制协议. TCP协议是面向连接的,可靠的,基于字节流的传输协议.在基于 TCP 进 ...
- nodejs学习笔记之网络编程
了解一下OSI七层模型 OSI层 功能 TCP/IP协议 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层 数据格式化 ...
- TCP/IP协议头部结构体(网摘小结)(转)
源:TCP/IP协议头部结构体(网摘小结) TCP/IP协议头部结构体(转) 网络协议结构体定义 // i386 is little_endian. #ifndef LITTLE_ENDIAN #de ...
- TCP与UDP区别小结
TCP(Transmission Control Protocol):传输控制协议 UDP(User Datagram Protocol):用户数据报协议 主要从连接性(Connectiv ...
- 【TCP/IP详解 卷一:协议】TCP的小结
前言:TCP学习的综述 在学习TCP/IP协议的大头:TCP协议 的过程中,遇到了很多机制和知识点,详解中更是用了足足8章的内容介绍它. TCP协议作为 应用层 和 网络层 中间的 传输层协议,既要为 ...
- TCP的数据传输小结
TCP的交互数据流 交互式输入 通常每一个交互按键都会产生一个数据分组,也就是说,每次从客户传到服务器的是一个字节的按键(而不是每次一行) 经受时延的确认 通常TCP在接受到数据时并不立即发送ACK: ...
- TCP服务和首部知识点小结
服务 应用程序会被TCP分割成数据段,而UDP不分割. TCP有超时重传和确认 如果检验和出错将丢弃 IP数据包可能会失序或者重复,所以TCP会处理 滑动窗口来进行流量控制 对字节流的内容不做任何解释 ...
随机推荐
- MySql 使用教程(摘自网络)
一.连接 mysql 格式:mysql-h 主机地址 -u 用户名 p 用户密码 1 例 1 连接到本机上的 mysql 首先在打开 DOS 窗口,然后进入目录 mysql\bin ...
- 李明杰的视频和李明杰的博客是学习OC的基础
http://www.cocoachina.com/bbs/read.php?tid=196664
- 366. Find Leaves of Binary Tree C#
Example:Given binary tree 1 / \ 2 3 / \ 4 5 Returns [4, 5, 3], [2], [1]. Explanation: 1. Removing th ...
- double hashing 双重哈希
二度哈希(rehashing / double hashing) 1.二度哈希的工作原理如下: 有一个包含多个哈希函数(H1……Hn)的集合.当我们要从哈希表中添加或获取元素时,首先使用哈希函数H1. ...
- python 基础学习1
1.注释 与shell一样,python也是以#开始为注释语句 2.运算符 + - * / // ** python中有2种除法:单斜杠是普通除法,双斜杠是浮点数除法(结果四舍五入) < < ...
- 在eclipse中生成实体类
1.在eclipse的windows中选中preferences在查询框中输入driver definition 2.点击add在Name/type中选中mysql jdbc driver 5.1然后 ...
- Linux下各类压缩文件命令小结
.tar 解包:tar xvf FileName.tar 解包后原始文件仍存在 打包:tar cvf FileName.tar DirName1 Filename1 - 列出内容:tar tvf ...
- Adding DOM elements to document
1.JavaScript 添加DOM Element 执行效率比较: 抄自:http://wildbit.com/blog/2006/11/21/javascript-optimization-add ...
- mybatis拦截器分页
package com.test.interceptor; import java.sql.Connection; import java.sql.ResultSet; import java.sql ...
- Java Web 开发环境快速搭建
Java Web 开发环境快速搭建 在因某种原因更换开发设备后,可依据此文快速搭建开发环境,恢复工作环境. Java开发环境: Windows 10 (64-bit) Oralce JDK Eclip ...