1. TCP与TCP/IP协议族

TCP是TCP/IP协议族中运输层的一个协议。TCP/IP,即传输控制协议/网间协议,是一个工业标准的协议集,包含了运输层、网络层和链路层的协议,其结构如下图所示:其中socket是API接口,它将TCP/IP协议族包装了起来,应用层通过socket抽象层在网络中传输数据。

2. TCP特点

  1. 面向连接的运输层协议。即在传输数据之前,都要通过三次握手建立连接;关闭连接时,通过四次挥手关闭连接。这也是TCP协议区别于UDP协议的地方,是TCP提供可靠运输的基本原理,是TCP最最基本和重要的特性。而UDP因为不用连接和确认,所以效率高很多,但是质量就不保证。
  2. 每一条TCP连接唯一地被通信两端的两个端点(套接字)所确定。这也是TCP面向连接这一基本特性的体现,即它需要标识每一条连接的两个端点。这个端点叫做套接字(socket),用IP地址和端口号合起来表示一个socket:
    1. 套接字socket = (IP地址:端口号)
    2. TCP连接 = {socket1, socket2} = { (IP1: port1), (IP2: port2) }
  3. 提供可靠交付。即通过TCP连接传送的数据:无差错、不丢失、不重复、按序到达。相对的,UDP就是不可靠交付。这是以面向连接这个特性作为基础,辅以下述措施实现:
    1. 停止等待协议:发送完一个分组就停止发送,等待对方确认,需要处理超时重传
    2. 连续ARQ协议:ARQ(automatic repeat request)是自动重传请求,指使用超时重传及确认丢失和确认迟到机制的协议,其重传请求自动进行的,不需要接收方请求。而连续ARP协议指:维护发送窗口,连续发送窗口内的m个分组,不需要发一个等一次确认,接收方一般采用累积确认(对按序到达的最后一个分组确认),这样可以提高信道利用率。连续ARQ协议阐述了滑动窗口协议的基本概念。
    3. 滑动窗口协议:TCP协议的精髓所在,由此也可以加速传输,并实现流量控制。连续ARQ中也讲了,一次把滑动窗口内的数据都发送出去,接收方对按序到达的最大序号给出确认,如果收到确认(可以累积确认),窗口前移(未收到确认时,要保留已发送的数据,以便超时重传)。而窗口的大小是实现流量控制的关键所在,它是由接收方根据自己的接受情况确定的。可以参照这篇文章的分析。
      • 如下图四中所示,由接受者通告窗口大小为4~9,即6个字节的大小;而在当前窗口中,字节4~6已经发送,未被确认;字节7~9可以发送但未被发送;如果字节4~6被全部或部分按序确认了,例如序号4被确认了,然后窗口大小又没变,则窗口滑动,变为5~10;如果窗口大小变小了(接收方通知的),那么可能窗口就不会前移;但是窗口一般不赞成向后收缩,因为收缩时可能有些数据已经发送了。
      • 再如图5-22,其中发生了三次窗口调节,初始窗口大小为400字节,B确认前200字节时,将窗口重设为300字节,确认201~500字节时,窗口重设为100字节,确认501~600字节时,窗口重设为0。零窗口可能导致死锁:如果B的接收缓存有空余了,发送了新的窗口大小报文段,但是该报文段传送时丢失,而A一直等B的新窗口大小,B一直等A的数据,就出现死锁。解决方法:为每个连接设置持续计时器,如果A接收到零窗口通知,就启动计时器,到时间A就发送一个零窗口探测报文段,如果B给的窗口值还是0,计时器重启,如果不是0,死锁僵局就被打破。
  4. 面向字节流。TCP把程序的数据看作无结构的字节流,例如发送方可能发送了10个数据块,而TCP可能只用4个数据库就发送给接收方。它不在乎数据结构,只要把数据的每个字节都按序发过去就ok了。
  5. 全双工通信。TCP连接两端都设有发送缓存和接收缓存,发送方把数据发送给TCP后就可以干自己的事了,TCP看情况发出去(滑动窗口限制);接收时,TCP把数据放到接收缓存,应用进程合适的时候去读缓存就可以了(当接收缓存满了,TCP主动向上交付,但在PSH=1时,则会立即交付,下边会讲)。所以这给发送方和接收方很大的自由,只要TCP的发送缓存还有空间,他们都可以在任一时间发送数据。

 

3. TCP报文

上边讲的TCP的很多特点:面向连接、可靠传输、窗口等,都是通过其报文的字段实现的。

TCP报文段分两部分:首部(20+4N字节)和数据部分。首部前20字节是固定的,后4N(N是整数)字节是根据需要可以增加的。对其中的某些字段做解释:

  1. 序号:指该TCP连接当前发送的报文段的第一个字节的字节序号,标识当前发送的数据块。每个字节都有序号,序号连续增加,当序号增加到232-1之后,就又变为0.
  2. 确认号:指接收方对发送方发送数据的确认,是期望收到的下一个字节序号。如A向B发送200字节数据,发送序号为301(即发送了301~500的数据),则B向A确认时,确认号为501。若确认号=n,说明到n-1为止的数据都已确认收到了。
  3. 数据偏移:数据起点距TCP报文起始点的距离,即首部长度(因为有后4N不确定选项)
  4. URG:从这开始的六个字节,是控制位,上边的特点主要通过控制位实现。URG=1:表示当前报文有紧急数据要传送,相当于高优先级的,发送方TCP就把紧急数据插到该报文段最前面优先发送。注意,即使窗口为0也可以发送紧急数据。需要和下边的 紧急指针 结合使用。例如ctrl+c撤销就可能是一个紧急数据。
  5. ACK:ACK=1,确认号才有效,就是说这才是一个带有确认功能的报文。在连接建立以后,所有传送的报文段都必须把ACK置1.
  6. PSH:PSH=1,表示发送方希望能尽快收到接收方的响应,此时,数据到达TCP的接收缓存时,无论接收缓存是否填满,都立即向上交付给应用进程。(该操作很少用)
  7. RST:RST=1,复位,表示当前连接存在很大问题,需要重新建立连接,有时也用来拒绝非法报文段或拒绝打开一个连接。当发送RST包关闭连接时,无需通过四次挥手,可以直接关闭。而由于这并不是TCP连接中必须的一部分,因此不需要将ACK置1(对应上边连接建立后,ACK必须置1),但可以置1。 这是个很危险的字段,可能被用来实现RST攻击:假设有一个合法用户(1.1.1.1)已经同服务器建立了正常的连接,攻击者构造攻击的TCP数据,伪装自己的IP为1.1.1.1,并向服务器发送一个带有RST位的TCP数据段。服务器接收到这样的数据后,认为从1.1.1.1发送的连接有错误,就会清空缓冲区中建立好的连接。这时,如果合法用户1.1.1.1再发送合法数据,服务器就已经没有这样的连接了,该用户就必须重新开始建立连接。 因此在面试中经常会问产生RST包的各种原因:
    1. 服务器端口未打开而客户端来连接。很常见,特别是服务器程序core dump之后重启之前连续出现RST的情况会经常发生。但是某些os的原因,可能不会出现这种状况,如向一台win7主机发送一个连接不存在的端口的请求,这台主机就不会响应。
    2. 连接超时。例如89、27两台主机,89主机用setsockopt的SO_RCVTIMEO选项设置了recv的超时时间,然后89向27发送SYN包请求连接,27回应了一个SYN表示可以连接,但是回应太慢,超过了那个recv时间限制,所以89就直接又发了个RST包,又拒绝连接了。
    3. 提前关闭。服务器就是想要尽快关闭连接,就可以发送一个RST。
    4. 收到一个不存在的连接上的报文。如TCP收到一个报文,但是根据它的端点套接字,找不到一个符合要求的套接字对(表示一条连接,前文讲的),那说明此连接有错了,就发送一个RST包。
  8. SYN:用于连接建立时同步序号。SYN=1就表示是一个连接请求或连接接收报文,是在三次握手的前两次握手中使用
  9. FIN:用于释放连接,所以不能和SYN同时使用。所有SYN/FIN的包都是非法包。此外由于连接还没有关闭,所以还要打上ACK标记,即是FIN/ACK包,仅由FIN标记的包是不合法的。FIN报文段即使不携带数据,也要占一个序号
  10. 窗口:这就算上边接收方通知发送方的窗口大小,即接收方接收缓存大小。

根据上边的解释,就可以总结一些常见的非法包:SYN/FIN包、FIN包、NULL包(没有任何标记的包)

4. TCP建立连接---三次握手

1. (A) --> [SYN] --> (B)

假如服务器B和客户机A通讯. 当B要和A通信时,A首先向B发一个SYN (Synchronize) 标记的包,告诉B请求建立连接.

注意: 一个 SYN包就是仅SYN标记设为1的TCP包(参见TCP包头Resources). 认识到这点很重要,只有当B受到A发来的SYN包,才可建立连接,除此之外别无他法。因此,如果你的防火墙丢弃所有的发往外网接口的SYN包,那么你将不 能让外部任何主机主动建立连接。

2. (A) <-- [SYN/ACK] <--(B)

接着,B收到后会发一个对SYN包的确认包(SYN/ACK)回去,表示对第一个SYN包的确认,并继续握手操作.

注意: SYN/ACK包是仅SYN 和 ACK 标记为1的包.

3. (A) --> [ACK] --> (B)

A收到SYN/ACK 包,A发一个确认包(ACK),通知B连接已建立。至此,三次握手完成,一个TCP连接完成

Note: ACK包就是仅ACK 标记设为1的TCP包. 需要注意的是当三此握手完成、连接建立以后,TCP连接的每个包都会设置ACK位

这就是为何连接跟踪很重要的原因了. 没有连接跟踪,防火墙将无法判断收到的ACK包是否属于一个已经建立的连接.一般的包过滤(IpchBins)收到ACK包时,会让它通过(这绝对不是个 好主意). 而当状态型防火墙收到此种包时,它会先在连接表中查找是否属于哪个已建连接,否则丢弃该包

5. TCP释放连接(四次挥手)

TCP相关知识的更多相关文章

  1. TCP相关知识总结

    参考: http://coolshell.cn/articles/11564.html http://coolshell.cn/articles/11609.html TCP头格式 接下来,我们来看一 ...

  2. 【转】java NIO 相关知识

    原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...

  3. 【转载】前端面试“http全过程”将所有HTTP相关知识抛出来了...

    原文:前端面试“http全过程”将所有HTTP相关知识抛出来了... 来一篇串通,一个http全过程的问题,把所有HTTP相关知识点都带过一遍 http全过程 输入域名(url)-->DNS映射 ...

  4. HTTP协议知多少-关于http1.x、http2、SPDY的相关知识

    作为网站开发的基础协议,我们知道浏览器上都有输出http这四个字母,这意味着什么呢? 这就是最基础的HTTP协议. 逐浪君今天为各位大人准备了一些HTTP技术的知识,来和大家分享. 以下图为例: 这一 ...

  5. 《Python网络编程》学习笔记--从例子中收获的计算机网络相关知识

    从之前笔记的四个程序中(http://www.cnblogs.com/take-fetter/p/8278864.html),我们可以看出分别使用了谷歌地理编码API(对URL表示地理信息查询和如何获 ...

  6. [转帖]xserver相关知识汇总

    xserver相关知识汇总 https://blog.csdn.net/QTVLC/article/details/81739984   本文主要是从以下几个方面介绍xorg-xserver 相关的知 ...

  7. web聊天相关知识

    http相关知识 http是无状态,请求,响应模式的通信模式,就是用户每次通过浏览器点击一下页面,都需要重新与web服务器建立一下连接,且发送自己的 session id 给服务器端以使服务器端验证此 ...

  8. 【Stream—6】BufferedStream相关知识分享

    一.简单介绍以下BufferedStream 在前几章的讲述中,我们已经能够掌握流的基本特性和特点,一般进行对流的处理时,系统肩负着IO所带来的开销,调用十分频繁,这时候就应该想个办法减少这种开销,而 ...

  9. 【Stream—7】NetworkStream相关知识分享

    一.NetworkStream的作用 和先前的流有所不同,NetworkStream的特殊性可以在它的命名空间中得以了解(System.Net.Sockets),聪明的你马上就会反应过来:既然是在网络 ...

随机推荐

  1. Android开发的十项注意

    随着移动平台的发展及其应用的不断改善,质量成为决定成败的关键.用户要求他们安装的应用响应快.性能好,如果某个应用不能提供卓越的功能和稳定的用户体验,那注定会被很快卸载: 尽管现在Android智能手机 ...

  2. 使用SSIS创建同步数据库数据任务

    国外相关的文章:http://blog.dxuf.com/sql-tutorial/use-ssis-to-create-the-synchronization-database-data-task. ...

  3. 在window 下安装Memcache详解

    有时候我们需要在本地测试的时候就用到memcahce,如果本地没有安装memcache,就会有下面的错误提示: 1234567 系统发生错误 您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ...

  4. 【SNMP】Linux系统下安装net-snmp

    这里使用的snmp的版本是net-snmp-5.7.3下载地址:http://www.net-snmp.org/download.html 安装步骤: 1.解压缩安装包: tar -xzvf net- ...

  5. Cocos2d-JS中的cc.LabelTTF

    cc.LabelTTF是使用系统中的字体,它是最简单的标签类.cc.LabelTTF类图如下图所示,可以cc.LabelTTF继承了cc.Node类,具有cc.Node的基本特性. LabelTTF类 ...

  6. SQL 建表与查询 HTML计算时间差

    create database xue1 go --创建数据库 use xue1 go --引用数据库 create table xinxi ( code int, name ), xuehao ), ...

  7. 数值积分NIntegrate中的具体算法

    数值积分方法很多,Mathematica中至提供了NIntegrate.具体算法可参照官方帮助. http://reference.wolfram.com/language/tutorial/NInt ...

  8. [翻译.每月一译.每日一段]Exploring Fonts with DirectWrite and Modern C++

    Windows with C++ Exploring Fonts with DirectWrite and Modern C++ Kenny Kerr DirectWrite is an incred ...

  9. Git tricks: Unstaging files

    NOTE: Following content is directly reprinted from http://andrewberls.com/blog/post/git-tricks-unsta ...

  10. git使用小结

    本篇文章主要介绍自己在平时工作中使用git的一些常用命令,之前都是记录在本子上面,现在把他们记录在博客上,便于保存和回顾. 1. 建立自己的git仓库 1.1 在一个新建的repo文件夹里面,执行gi ...