热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TCPIP协议笔记

最近在读《图解TCPIP》,主要是想解决以下困惑:1.为什么TCP是面向连接的。2.为什么TCP是可靠的(数据包不会乱序,不丢包)3.为什么TCP适合传

最近在读《图解TCP/IP》,主要是想解决以下困惑: 1.为什么TCP是面向连接的。 2.为什么TCP是可靠的(数据包不会乱序,不丢包) 3.为什么TCP适合传输大量数据 4.为什么TCP传输速度比较慢

什么是TCP/IP协议

TCP协议是OSI(Open System Interconnect)中的第4层传输层,IP协议位于OSI中的第3层的网络层,传统的OSI中有7层,现行的tcp/ip协议族选用了5层架构,把会话层和表示层的功能整合在了应用层。从字面上看TCP/IP是指TCP和IP两种写一下,但是IP或ICMP(Internet Control Message Protocol)、TCP和UDP、FTP、HTTP都属于TCP/IP协议,所以才会说是tcp/ip协议族。 它是为了解决传输的稳定性,连续性,和安全性而产生的。

为什么TCP是面向连接的

其实端到端之间的连接是没有连接这一说的,TCP之所以说是面向连接的,是因为发送方和接收方各自维护了一组状态,以保证双方的状态能够同步,从而看上去是有连接的。TCP协议维护了以下状态

状态状态描述
CLOSED每个连接开始建立之前默认的状态
LISTEN一台设备(通常是服务器)等待接受来自客户端的SYN(Synchronize Sequence Numbers 同步序列号),这时候还没发送自己的SYN
SYN-SENT一台设备(通常是客户端)发送了SYN,并且等待匹配来自其他设备(通常是服务端)的SYN
SYN_RECEIVED两端设备都接收到SYN并发送了自己的SYN,现在就等待接受ACK(Acknowledgement Number)从而建立连接
ESTABLISHED一个TCP连接在两端都已准备就绪,两端能够自由的交换数据,直到这个连接被某一端主动关闭
CLOSE-WAIT设备收到来自另外一端的关闭连接请求FIN(Finish Number),这时候设备会接受这个请求并生成对应ACK
LAST-ACK当设备收到一个FIN并发送了对应的ACK,然后发送了自己的FIN并等待对方的ACK回复
FIN-WAIT-1处于这个状态下的设备等待自己发送FIN后对方的ACK应答,或者是等待接收另一端终止连接的请求
FIN-WAIT-2处于这个状态下的设备已经接收到自己发送出去的FIN对应的ACK,并等待另一端的FIN请求并发送自己的ACK
CLOSING设备收到了另一端的FIN并且发送了对应的ACK给了对方,但是还没收到他自己发送的FIN对应的ACK
TIME-WAIT双方设定都发送了FIN,并都接收到了对应的ACK,这时候连接已经完成了,但是连接不会立刻关闭,防止有新的连接复用

再放上状态改变图,对照表格更好的理解状态改变

TCP协议有这么多连接状态,也就意味着这个协议有多复杂。再加上网络环境的复杂性和不可预知性,因此要是想把TCP协议写完整不是一朝一夕的事情。

为什么TCP是可靠的(数据包不会乱序,不丢包)

在网络OSI(Open System Interconnection)中,TCP位于第4层,我们的网络数据会放在TCP的Segment(一段网络数据会划分成许多Segment)的body中,然后Segment会放到IP层的Packet中,再放到数据链接层的Frame中,传到另一端后,逐层解析各自的协议,然后交给上层处理。 一个TCP Segment的Header里有如下字段:

当完成TCP三次握手后,建立连接。当我们有一段数据需要传输时,TCP会将数据拆分成一个个Segment,每个Segmen会有一个序号。假设我们有40个Segment需要传输:

Seq代表了建立连接后的一个数字,不一定从1开始,双方都会确立一个ISN(Inital Sequence Number)确立一个初始化序列号,在一个连接周期内(RFC定义为4.55小时)会不断增加,确保不重复。发送数据端的Seq会随着数据包传输的长度进行累加。 TCP用以下机制来保证数据的完整性和顺序性: 超时重传机制:当发送端连续发送数据包而没有收到接收端的ack时,会动态计算一个timeout,当在发出数据后,在timeout内没有收到ack,会启动重传机制,以接收方最后一个ack序号,往后发送数据,若依旧没有在timeout内有ack回复会进入timeWait。这个机制重度依赖于timeout的计算算法。

快速重传机制:当接收方返回的ack序号连续保持一致时,可以认为数据包丢失,需要启动快速重传,以接收方最后一个ack序号,往后发送数据。

快速重传机制和超时重传机制有一个问题无法解决,那就是无法决定只重传ack所确定的那个包,还是往后的所有包。 比如有5个包,12已收到ack,发送345后没有收到ack,这时候是选择只重传3呢,还是重传345呢。这时候就需要SACK出马了。 **SACK(Selective Acknowledgment)**在TCP头部中会添加一个SACK字段用来表示接收到的字段区间。当接收端将ack和SACK发送给发送端后,发送端就知道哪些数据需要重传。

为什么TCP适合传输大量数据

因为大量数据会被tcp协议分成一个个segment,然后给每个segment编号,根据SequenceNumber发送数据,接收端根据SequenceNumber来拼接数据,保证数据的完整性。

为什么TCP传输速度比较慢

首先TCP作为传输层协议,不但要对端对端的连接负责,还要对整个网络的连接负责。因此既要保证单一连接的我稳定性,也要保证整个网络的稳定性,当网络情况出现波动时,TCP有能尽量的调整自己的发包速度,避免加重网络堵塞。 因此TCP头部利用Window字段和RTT(Round Trip Time,也就是一个数据包从发出去到收到ack的时间)以及RTO(Retransmission TimeOut)来动态改变传输的速度。 决定传输速度的是cwnd(Congestion Window),单位是MSS(Max Segment Size),以太网标准MSS是1460字节,最初慢启动的cwnd大小是3MSS。 Window : 也就是Sliding Window,滑动窗口,发送方根据接收方传过来的这个字段来决定发送多少数据。 慢启动 :当tcp开始传输后,每收到一个RTT,就会将cwnd * 2,很明显这是是一个指数增长的算法,直到达到threshhold,进入拥塞避免算法。因此我们下载东西,初期速度都会很小,网络条件好的情况下,几秒钟后就能达到最大速度。 拥塞避免 每收到一个ACK时,cwnd = cwnd + 1/cwnd,每过一个RTT时,cwnd = cwnd + 1,进入线性增长 拥塞发生 当RTT > RTO时,tcp认为网络条件差, threshhold = cwnd / 2, cwnd = 1,然后进入慢启动。 另外一种情况是两端都支持ECN的TCP连接中,假如在传输过程中出现拥塞,路由器会在传输的IP包的头部将ECN字段置为11,接收端收到这个ECN为11的包后,会将ACK包的ECE(Explict Congestion Notification Echo)字段置为11,发送端收到这个Ack后检查ECE,假如为11,也会进入慢启动和拥塞避免算法。

快速恢复 当收到多个重复Ack,cwnd = cwnd /2,sshthresh = cwnd,然后进入拥塞避免

参考文章

TCP 的那些事儿 关于TCP重连 图解TCP/IP The-TCP/IP-Guide TCPIP-Ref



推荐阅读
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 无线认证设置故障排除方法及注意事项
    本文介绍了解决无线认证设置故障的方法和注意事项,包括检查无线路由器工作状态、关闭手机休眠状态下的网络设置、重启路由器、更改认证类型、恢复出厂设置和手机网络设置等。通过这些方法,可以解决无线认证设置可能出现的问题,确保无线网络正常连接和上网。同时,还提供了一些注意事项,以便用户在进行无线认证设置时能够正确操作。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • SQL Server 内存中OLTP内部机制概述(一)
    内存中OLTP(项目名为“Hekaton”)是一个新的完全集成到SQLServer中的数据库引擎组件。它专为访问内存常驻数据的OLTP工作负荷而进行优化。内存中OLTP有助于OLT ... [详细]
author-avatar
叶韵
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有