概述:

  • TCP传输前先要建立连接
  • TCP在传输层
  • 点对点,一条TCP只能连接两个端点
  • 可靠传输、无差错、不丢失、不重复、按顺序
  • 全双工
  • 字节流

TCP报文段

TCP报文段的报头前20字节是固定的,后面4n字节是根据需要而添加的。

20字节的固定部分:

  • 源端口和目的端口:分别写入源端口号和目的端口号
  • 序号:0-(2^32-1),本报文段数据的第一个字节的序号,用来解决乱序问题
  • 确认序号:期望收到对方下一个报文段的第一个数据字节的序号,用来解决丢包问题
  • 数据偏移:TCP报头长度,包括固定的20字节和选项字段
  • 保留:均为0
  • 控制位:说明报文的性质,操控TCP的状态机

  • 窗口:指发送者自己的接收窗口大小,流量控制
  • 校验和:
  • 紧急指针:当URG=1时才有效,指出本报文段紧急数据的字节数
  • 选项:

连接的建立与释放

三次握手:

(1)client发出请求连接报文段,SYN=1,Seq=x。client进入SYN-SENT状态。

(2)server收到请求报文后,向client发送确认报文段。确认报文段的首部中SYN =1,ack = x + 1,同时为自己选择一个初始序列号Seq = y.server进入SYN-RCVD(同步收到)状态。

(3)client收到server的确认报文后,还有给server发送一个确认报文。 确认号ack = y + 1,而自己的Seq = x + 1。这个报文段已经可以携带数据,如果不携带数据则不消耗序号,下一个报文段序号仍为Seq = x + 1。

为什么要三次握手呢?

假设握手只有两次,如果某次数据报由于网络延迟,从client到server时,已经断开连接了,而此时server会认为是client想建立一个新的连接,于是发给client一个确认报文(第二次握手)就建立了新的连接了,显然这是错误的。如果是三次握手,client接到这个确认报文时,不予理睬,两者没有完成第三次握手,所以不会建立错误的连接了。

网上有一个比较形象的说法:

第一次对话:

老婆让甲出去打酱油,半路碰到一个朋友乙,甲问了一句:哥们你吃饭了么?
结果乙带着耳机听歌呢,根本没听到,没反应。甲心里想:跟你说话也没个音,不跟你说了,沟通失败。说明乙接受不到甲传过来的信息的情况下沟通肯定是失败的。
如果乙听到了甲说的话,那么第一次对话成功,接下来进行第二次对话。

第二次对话:

乙听到了甲说的话,但是他是老外,中文不好,不知道甲说的啥意思也不知道怎样回答,于是随便回答了一句学过的中文 :我去厕所了。甲一听立刻笑喷了,“去厕所吃饭”?道不同不相为谋,离你远点吧,沟通失败。说明乙无法做出正确应答的情况下沟通失败。
如果乙听到了甲的话,做出了正确的应答,并且还进行了反问:我吃饭了,你呢?那么第二次握手成功。
通过前两次对话证明了乙能够听懂甲说的话,并且能做出正确的应答。接下来进行第三次对话。

第三次对话:

甲刚和乙打了个招呼,突然老婆喊他,“你个死鬼,打个酱油咋这么半天,看我回家咋收拾你”,甲是个妻管严,听完吓得二话不说就跑回家了,把乙自己晾那了。乙心想:这什么人啊,得,我也回家吧,沟通失败。说明甲无法做出应答的情况下沟通失败。
如果甲也做出了正确的应答:我也吃了。那么第三次对话成功,两人已经建立起了顺畅的沟通渠道,接下来开始持续的聊天。
通过第二次和第三次的对话证明了甲能够听懂乙说的话,并且能做出正确的应答。
可见,两个人进行有效的语言沟通,这三次对话的过程是必须的。

 

四次挥手

(1)此时TCP两端都还处于ESTABLISHED状态,client不再发送数据,并发送一个FIN报文段,seq = 1,进入FIN-WAIT-1状态。

(2)server收到后回复,ack = u + 1,seq = v(v等于服务器传输数据最后一字节的序号加1),然后进入CLOSE-WAIT状态,server如果继续发送数据,client依然接收。

(3)client收到确认报文后,进入FIN-WAIT-2状态。server不再发送数据后,发出FIN,ack = u  + 1,进入LASK-ACK状态。

(4)client收到后回复,seq = u + 1, ack = w + 1(w 等于服务器后来继续发送的最后一个字节的序号加1,与v并不一定相等!),然后进入TIME-WAIT状态

(5)此时连接还没有释放,需要等待(4分钟)两端才会CLOSED。设置时间等待是因为有可能最后一个确认报文丢失而需要重传。

为什么要四次挥手呢?

因为当client发送FIN是,表示client没有要传的数据了,不代表server没有数据要传给client,所以server还需要发送FIN来表示它也没数据传输了。由于TCP是全双工的,所以并不存在谁先FIN的问题。

SYN超时问题:server如果在一定时间内没有收到client的确认报文,会重发。在Linux下,默认重试次数为5次,5次重试的时间分别为1、2、4、8、16、32s。第五次都没有收到,就会断开这个连接。

SYN Flood攻击问题:如果给服务器发送一个SYN后,就下线了,于是服务器就需要等63秒才会断开连接,这样攻击者就可以把服务器的SYN连接队列耗尽。Linux下有一个叫tcp_syncookies的参数来应对这个事。当SYN队列满了以后,TCP会通过源地址端口、目标地址端口和时间戳打造一个特别的Seq Number发回去(又叫cookie),如果是攻击者则不会有相应,如果是正常连接,则会把这个SYN Cookie发回来,然后服务端可以通过cookie建立连接。千万不要用tcp_syncookies来处理正常的大负载的连接的情况。对于正常的请求,应该调整TCP参数,第一个是:tcp_synack_retries可以用他来减少重试次数;第二个是:tcp_max_syn_backlog,可以增大SYN连接数;第三个是:tcp_abort_on_overflow处理不过来感觉直接拒绝连接!

TCP可靠传输的实现

  • TCP报文段的长度可变,根据收发双发缓存、网络状态而调整。
  • TCP收到另一端数据时,会回发确认
  • TCP能够超时重传
  • 数据校验
  • 报文段中有序号,以保证顺序正确
  • TCP提供流量控制

发送者再发送一个报文段后,暂时保存该文段的副本,收到确认后才删除;

确认报文段也需要序号,才能明白是发出去的那个数据得到了确认;

超时计时器比传输往返时间略长,但具体值不确定,根据网络情况而定(使用RTT算法)。

连续ARQ协议

实际中为了提高效率,采用流水线传输:发送方可以连续发送多个报文段(连续发送的数据长度叫做窗口)。接收方也不必对收到的每个报文都做回复,而是采用累积确认方式;

流量控制和拥塞控制

由于接收方缓存限制,发送窗口不能大于接受方接受窗口。
 

参考资料:《TCP那些事(上)》http://coolshell.cn/articles/11564.html

实验楼 TCP/IP网络协议基础 https://www.shiyanlou.com/courses/98

计算机网络 学习笔记-传输层:TCP协议简介的更多相关文章

  1. (传输层)TCP协议

    目录 首部格式数据单位特定注意自动重传请求ARQ具体实现发送缓存接收缓存滑动窗口确认丢失和确认迟到超时重传时间选择报文段的发送时机运输连接发送TCP请求客户端拥塞处理相关概念避免拥塞具体实现TCP 的 ...

  2. 传输层TCP协议

    目录 首部格式数据单位特定注意自动重传请求ARQ具体实现发送缓存接收缓存滑动窗口确认丢失和确认迟到超时重传时间选择报文段的发送时机运输连接发送TCP请求客户端拥塞处理相关概念避免拥塞具体实现TCP 的 ...

  3. OSI模型第四层传输层--TCP协议

    1.传输层2个协议tcp和udp 2.tcp的可靠性(挂号信). 面向链接的:类似寄挂号信,对方收到了并且能够确认.所以也是可靠的传输. 最大报文传输:两端可以协商传输报文大小.(协商一个报文的大小) ...

  4. 传输层tcp协议以及scoket套字节方法

    一.传输层 1.传输层的由来: 网络层的IP帮我们区分子网 以太网的Mac帮我们找到主机 所以通过IP和Mac找到了一台特定的主机 如何找到该特定主机的应用程序呢? 答案是通过端口,端口即应用程序与网 ...

  5. [计网笔记] 传输层---TCP 传输层思维导图

    传输层思维导图 TCP笔记 为什么是三次握手和四次挥手 https://blog.csdn.net/baixiaoshi/article/details/67712853 [问题1]为什么连接的时候是 ...

  6. TCP/IP五层模型-传输层-TCP协议

    ​1.定义:TCP是一种面向连接.可靠的.基于字节流的传输控制协议. 2.应用场景:TCP为可靠传输,适合对数据完整性要求高,对延时不敏感的场景,比如邮件. 3.TCP报文:①TCP报文格式: ②TC ...

  7. Java学习笔记之基于TCP协议的socket

    可以一直输入,而不是一问一答: 开两个线程,一个负责收,一个负责发. 1.先运行: package com.zr.javase0825; import java.io.BufferedReader; ...

  8. [TCP/IP] 传输层-TCP和UDP的使用场景

    传输层-TCP和UDP应用场景 TCP(传输控制协议) 需要将要传输的文件分段传输,建立会话,可靠传输,流量控制 UDP(用户报文协议) 一个数据包就能完成数据通信,不需要建立会话,不分段,不用流量控 ...

  9. [转帖]传输层安全协议TLS 1.3 RFC 8446使互联网更快、更安全

    传输层安全协议TLS 1.3 RFC 8446使互联网更快.更安全 2018-08-12 11:38:19作者:LINUX人稿源:开源社区 https://ywnz.com/linuxyffq/261 ...

随机推荐

  1. iOS Xcodebuild

    简介 xcodebuild 是苹果发布自动构建的工具.它在一个Xcode项目下能构建一个或者多个targets ,也能在一个workspace或者Xcode项目上构建scheme,总的来说,用它没错就 ...

  2. Android Priority Job Queue (Job Manager):多重不同Job并发执行并在前台获得返回结果(四)

     Android Priority Job Queue (Job Manager):多重不同Job并发执行并在前台获得返回结果(四) 在Android Priority Job Queue (Jo ...

  3. C#代码示例_调试

    调试信息 可使用如下两个命令输出调试信息: l Debug.WriteLine() l Trace.WriteLine() 这两个命令函数的用法几乎完全相同,但有一个重要区别.第一个命令仅在调试模式下 ...

  4. Android关联源码support-v4,v7,v13源码(转)

    在Android实际开发过程中往往会遇到使用v4,v7或v13兼容包中的一些类如ViewPager,Fragment等,但却无法关联源码. 在网上搜索之后,有很多办法,这里只向大家介绍一种,我用的觉得 ...

  5. Android-->猜拳小游戏

    --> 简单的 页面跳转 和 点击事件 的实现... --> AndroidManifest.xml <?xml version="1.0" encoding=& ...

  6. Egit Patch

    Git为我们提供了Patch功能,Patch中包含了源码更改的描述,能够应用于其他Eclipse工作空间或者Git仓库.也就是说,可以将当前提交导出至其他分支或者项目中. 举个例子,项目A.B中使用了 ...

  7. XPath注入笔记

    XPath注入 XQuery注入 测试语句:'or '1'='1 利用工具: Xcat介绍 Xcat是python的命令行程序利用Xpath的注入漏洞在Web应用中检索XML文档 下载地址:https ...

  8. Do It Wrong, Get It Right

    Do It Wrong, Get It Right Time Limit: 5000ms, Special Time Limit:12500ms, Memory Limit:65536KB Total ...

  9. animate.css 一些常用的CSS3动画效果

    大家已经开始在项目中使用一些CSS3动画效果了吧,这让网站在高端浏览器上看起来很上流.animate.css是一个老外做的各种CSS3动画的合集,比较全,也很炫,大家可以参考学习一下. 项目主页:ht ...

  10. px和em区别-在font-size的 css 的使用

    px像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的. em是相对长度单位.相对于当前对象内文本的字体尺寸,多理解父级设定font-size的尺寸.如当前对行内文本的字体尺寸未 ...