TCP_IP协议(传输层)笔记_传输层提供服务的对象-程序员宅基地

技术标签: Java  网络  linux  网络通信  

TCP/IP
应用层:程序员写代码的一层。HTTP、SSH、FTP、DNS
传输层:为了保证两端能够顺利的通讯。TCP、UDP
网络层:用来确定路线和路由选择。
数据链路层:相邻节点的数据接收和转换。

TCP两个对象(客户端和服务器端)
服务器:ServerSocket
客户端:Socket new Socket(IP,Port)

TCP读写数据的重要对象
读:BufferedReader socket.getInputStream 读取readLine()
写:BufferedWriter writer(“内容\n”)

TCP 与 UDP 的区别
UDP无连接;TCP是有连接的
UDP不稳定;TCP稳定
UDP面向数据报;TCP面向数据流
UDP只有接收缓存区,没有发送缓存区;TCP两个缓存区都有
UDP 和 TCP 使用场景不同,如果对稳定性要求比较高,应该使用TCP;如果对消息丢失不敏感,要求性能比较高,可以考虑使用UDP。

在这里插入图片描述
在这里插入图片描述



传输层

最大端口号:0-65535(2^16)

端口号分类
知名端口号:0-1023.。FTP:21;SSH:22;Telent:23;HTTP:80;HTTPS:443;Mysql:3306;Tomcat:8080
动态端口号:1024-65535

UDP协议

在这里插入图片描述
16位UDP长度 = UDP头部长度(8个字节) + 数据长度
UDP一个包的最大理论长度 = 2^16
16位源端口号:发送程序
16位目的端口号:找到接收程序
校验和:用来确定数据在传输过程中是否被篡改,用来判断数据的正确性。

如果UDP编程的时候数据大小大于64KB会怎样?
1.在应用层进行数据包的拆分和组合。
2.大于64KB不处理,交给TCP/IP协议取处理,它会在网络层进行分包和组包。

全双工与半双工
全:发送端或者是接收端,既能发送消息又能接收消息。
半:发送端只能发送消息,不能接收消息;接收端只能接收消息,不能发送消息。

基于UDP的应用层协议

  • NFS: 网络文件系统
  • TFTP: 简单文件传输协议
  • DHCP: 动态主机配置协议
  • BOOTP: 启动协议(用于无盘设备启动)
  • DNS: 域名解析协议

TCP 协议

在这里插入图片描述

4位首部长度
URG:0/1 表示是否为紧急指针。
ACK:是否确认应答消息
PSH:是否立即从缓冲区取走数据
RST:复位标识
SYN:同步序列号标识(TCP连接时候使用)
FIN :结束序列号标识 (TCP断开连接的时候)

TCP 8大特性

确认应答(ACK)

在这里插入图片描述

保障TCP稳定的核心机制

问题
发送消息丢失了
ACK丢失了
超时重发

Linux: 500ms

策略
发送不会以固定的频率发送,采用悲观策略,如果第一次失败,大概率第二次也会失败,TCP会以指数级超时时间增长的频率来发送消息。
如果经历了一定的重试次数,消息还没有得到应答,就会停止发送。

连接管理

3次握手 : 为了验证收、发两端的收、发能力。
4次挥手:为了确保发送端和接收端能够正常关闭。

在这里插入图片描述

服务端状态
[CLOSED -> LISTEN] :服务器端调用listen后进入LISTEN状态, 等待客户端连接;
[LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文;
[SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行读写数据了;
[ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器返回确认报文段并进入CLOSE_WAIT;
[CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN);
[LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接;
客户端状态
[CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
[SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
[ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入FIN_WAIT_1;
[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
[TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的
时间, 才会进入CLOSED状态.

TIME_WAIT 2 MSL(最大超时时间)

2 MSL = ACK 最大超时时间(1 MSL) + 对方发送给它消息的一个最大等待时间(1 MSL)。
如果程序中存在大量的CLOSE_WAIT 说明程序中存在BUG,没有调用close()主动关闭连接。


滑动窗口

在这里插入图片描述
窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 上图的窗口大小就是4000
个字节(四个段);
发送前四个段的时候, 不需要等待任何ACK, 直接发送;
收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推;
操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应搭,只有确认应答过的数据,才能从缓冲区删掉;
窗口越大, 则网络的吞吐率就越高;

情况一:数据包已经抵达,ACK被丢了
在这里插入图片描述
ACK = 6001的含义:并不是告诉主机A,已经成功收到5001~6000,而是告诉主机A,我成功接收了 0~6000.
ACK 返回的值是当前(主机B)接收缓冲区的下一个值(最大连续值)

情况二:数据包就直接丢了

在这里插入图片描述
当某一段报文段丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 “我想要
的是 1001” 一样;
如果发送端主机连续三次收到了同样一个 “1001” 这样的应答, 就会将对应的数据 1001 -
2000 重新发送;
这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实
之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中;
这种机制被称为 “高速重发控制”(也叫 “快重传”)

流量控制

以结果(接收缓冲区的大小)为导向进行数据的传递。
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应。因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制。

  • 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK端通知发
    送端;
  • 窗口大小字段越大, 说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;
  • 发送端接受到这个窗口之后, 就会减慢自己的发送速度;
  • 如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个
    窗口探测数据段, 使接收端把窗口大小告诉发送端
拥塞控制

网络更新当前时间的网络来动态调整收发的频率就叫拥塞控制。
TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;
在这里插入图片描述

  • 此处引入一个概念程为拥塞窗口;

  • 发送开始的时候, 定义拥塞窗口大小为1;

  • 每次收到一个ACK应答, 拥塞窗口加1;

  • 每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口;
    在这里插入图片描述

  • 为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍

  • 此处引入一个叫做慢启动的阈值

  • 当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长

  • 当TCP开始启动的时候, 慢启动阈值等于窗口最大值;

  • 在每次超时重发的时候,慢启动阈值会变成原来的一半, 同时拥塞窗口置回1;

  • 少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;

  • 当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;

  • 拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.

延迟应答
  • 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;
  • 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
  • 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
  • 如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是
    1M;
策略
每隔一段时间(固定时间)延迟应答一次;
每隔N次(>=2)延迟应答一次;

一定程度加速发送消息的速度。
延迟应答(200MS)的时间一定小于超时重传的时间(500MS)。
窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;

捎带应答

针对对于延时应答的性能优化。
在这里插入图片描述

TCP沾包问题

TCP 异常情况

  • 可挽救:电脑重启或者进程结束的时候,它会发送 FIN 请求,和正常关闭TCP是没有什么区别的;
  • 不可挽救:电脑掉电/网线中断:TCP 报活定时器,会定时检测对方是否在线,如果检测的结果是没有任何响应,说明已经掉线,直接释放连接。

小结

  • 稳定性:确认应答;超时重传;连接管理;流量控制;拥塞控制。
  • 保证性能:滑动窗口;延时应答;捎带应答。
  • 基于TCP应用层协议:HTTP;SSH;Telent;FTP:SMTP。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/XSAAA/article/details/115921728

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签