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

OSI7层模型(TCP4层)

控制报文中的回显请求和应答来实现的,traceroute是使用差错报文中的TTL超时报文和目标不可达报文实现的。网络层还有ARP和RARP协议用于在IP和MAC地址之间转换。网络接口层tcpip的网
控制报文中的回显请求和应答来实现的,traceroute是使用差错报文中的TTL超时报文和目标不可达报文实现的。 网络层还有ARP和RARP协议用于在IP和MAC地址之间转换。
网络接口层 tcp/ip的网络接口层对应OSI模型中的链路层和物理层,其传输的数据单位是帧(Frame)。在上层要发送的数据包的首部和尾部添加相关数据后封装成帧后发送出去,其主要有如下三个作用: 1、为网络层接收和发送ip数据报(IP datagram)。 2、为arp发送请求和接收数据。 3、为rarp发送请求和接收数据。
网络接口层协议有Ethernet协议、802.3等等,如下图展示了这两种协议的组成部分。


该层首部通常包含目的和源地址,就是设备的mac地址,尾部是一个CRC校验码,用于保证数据的准确性。 中间传输的数据域是有长度限制的,如802.3是从38到1492,ethernet协议是从46到1500。这里数据长度的限制是有传输介质的物理特性决定的,如果传输的数据长度不在该范围内,则该帧会被丢弃。这里就是MTU的出处了。
MTU(Maximal Transmission Unit),最大传输单位值,即可以一次性传输数据的最大值,该值往往受传输介质约束。在以太网协议中,MTU值为1500。一个帧的构成为7字节前导同步+1字节帧开始定界符+6字节的目的MAC+6字节的源MAC+2字节的帧类型+1500+4字节的FCS(校验码),最大值为1526。其实通过抓包工具获取的一个帧最大确实1514,原因在于数据帧到达网卡后,在物理层网卡会先去掉前导同步码和帧开始定界符,之后根据FCS进行验证,如果符合,将该帧交互设备驱动程序做进一步的处理,这个时候抓包工具才能抓到包,此时的帧也被去除了校验码,所以最终抓到的帧大小为6+6+2+1500=1514。传输数据有最大值也有最小值,当上层传输的数据小于最小值时(ethernet时46),比如tcp三次握手时的ack返回仅有20(tcp头部)+ 20(ip头部)= 40字节,小于最小值46字节。对于此种情况,网卡驱动程序会进行自动填充,但如果抓包工具先于驱动程序抓到该帧,那么其大小就要取决于抓包工具本身的显示,wireshark只是显示原大小。
上面对于链路层中的包长度进行了简单地说明,至此,TCP/IP的网络协议栈大致结束,下面以问答的形式讲解几个知识点。
***MTU是什么?MSS是什么?两者有什么关系吗? 答:MTU即Maximal Transmission Unit,最大传输单元,是指网络接口层中由于受传输介质的物理特性制约一次可以传送的最大字节数,如以太网中MTU为1500Byte。 MSS即Maximal Segment Size,最大段长度,是传输层中TCP报文段中数据段的最大长度,默认是536Byte。其存在的意义如下: 防止传输数据过小造成资源浪费。比如发送数据每次都是1Byte,在每一层都会添加首部(20Byte的TCP首部和20Byte的IP首部),之后才会完成发送。也就是说传送的41Byte中,只有1Byte是有效数据,这明显造成了资源的浪费。 防止传输数据过大造成传输效率降低。如果发送的数据过大,超过了MTU的值,那么在IP层就会出现分片现象,而接收方也要耗费更多的资源和时间来处理分片,如果在传输过程中发生丢片,也会进一步增大网络开销。 防止传输数据过大造成传输效率降低。如果发送的数据过大,超过了MTU的值,那么在IP层就会出现分片现象,而接收方也要耗费更多的资源和时间来处理分片,如果在传输过程中发生丢片,也会进一步增大网络开销。
有了MSS,TCP每次传输的数据都能被控制在一个i额合理的范围内,避免IP分片的发生,增大传输效率,最大化利用资源。
下图描述了MTU和MSS的关系,可以简单地理解为MTU=IPHeader + TCP Header + MSS。



下面这张图描述了TCP是如何在三次握手建立连接的过程中和对方协商MSS大小的。注意MSS只会出现在SYN包中。


***什么是半连接?SYN Flood是怎么一回事? 所谓半连接,就是还没有完成三次握手建立连接。具体是指服务端在收到客户端的SYN包后,会据此生成一个半连接的对象,并将其存储在一个半连接队列(SYN Queue)中进行维护。一旦收到客户端的ACK包后会将该对象从半连接队列(SYN Queue)转移到已连接队列(Accept Queue)中等待accept系统调用。一经accept调用,数据的传输和接收才会正式开始。队列肯定是不能无限长的,因为每个对象都会占据存储资源,内核配置中有两个参数对应这两个队列的长度。 /proc/sys/net/ipv4/tcp_max_syn_backlog,该参数指定了半连接队列的最大长度,队列达到该值时,后续的SYN请求会被拒绝。可以通过sysctl进行配置。 sk_max_ack_backlog,该参数指定了已连接队列的最大长度,队列达到该长度时,后续的连接请求会被拒绝。该参数一般是在listen系统调用中指定的,如listen(int sockfd, int backlog)中第二个参数。
SYN FLood攻击便是利用了半连接队列的长度限制来完成攻击的。攻击策略为伪造大量SYN包发送给服务端,但不返回ACK包,导致服务端半连接队列被迅速占满,正常的连接被抛弃。服务端会有大量处于SYN_RECV状态的连接,其会尝试重发ACK包给实际不存在的客户端,导致CPU满负载,内存耗尽,从而达到攻击效果。
一般可以通过修改.net.ipv4.tcp_synack_retries来减少重试发送ack的次数、开启net.ipv4.tcp_synCOOKIEs、调大net.ipv4.tcp_max_syn_backlog来进行防御。
***什么是粘包?怎么解决? 粘包是指服务端收到的数据出现不完整、混乱等情况。 粘包出现的原因是TCP数据的“流”特性。所谓“流”是指tcp传输的数据并不会在逻辑上进行划分,比如客户端给服务端发送了A和B两份数据,tcp发送的时候并不是分两次先发A数据,再发B数据,而是可能出现下面的情况: 1、先发送A和B的一部分,再发送B剩余部分 2、先发送A的一部分,再发送A剩余部分和B
可能有人问,我们在编程的时候不是直接调用了send(byte[])了吗?为什么数据会出现这种混乱的发送情况,原因有两个: 1、如果开启了Nagle算法,即tcp_no_delay是false,那么即便调用了send方法,tcp也不一定会立即将数据发送出去,而是会等待其他数据一同发送,这样做是为了最大化利用网络资源。 2、如果发送的数据过大,超过了MSS的大小,tcp会对数据进行分段发送,此时也不可能一次性将数据发送完毕。
这个时候服务端接收数据时该如何把A和B区分开呢?如果只是单纯地将一次接收的数据作为完整数据(A或B)处理,很容易出错。这里就引出了封包和拆包的概念。
所谓封包,就是将要传送的数据按照一个可辨识的结构传输,比如客户端和服务端约定传递的数据都遵从字节长度(4Byte)+实际数据的规则,那么服务端在解析数据(即拆包)的时候,就可以先读取4Byte,获取到一个完整数据的实际长度,然后再读取该长度的数据,之后再交由上层处理。
***socket的close和shutdown有区别吗? 有区别,这个设计到tcp关闭连接的方式,主要有两种: 1、一种是正常的通过4次握手关闭,这是优雅的方式,可以保证双方的数据都被接受。 2、一种是通过发送RST包的方式跳过4次握手快速关闭连接,这是暴力的方式,不安全。
close会直接关闭socket的文件描述符,包括输入和输出流,但shutdown只是在己方的输入输出流做了一些人为的处理,比如丢弃了输入流中的数据,直接返回EOF结束符和向输出流写入东西时报错等等,但并不会关闭socket,所以对方的连接依然可以正常读写,要关闭还是要调用close。
另外close只会关闭本进程的socket文件描述符,如果其还被其他进程调用,则实际不会被关闭。但shutdown却会影响所有使用了该socket的进程。无特殊情况,使用close关闭socket即可。 在shutdownOutput后,再写入时会报broken pipe的错误,对执行了close的socket读入时会报错:socket closed。
flush有必要吗? 基本无必要,我们在使用文件流的时候,都会强调一下flush函数,有时如果不主动调用,会导致写入的数据没有写到磁盘上,造成数据丢失,那么socket编程中是否要注意flush呢?
实际上当我们socketOutputStream.write(byte[])(java接口)的时候,数据已经发送出去,与flush无关。当然如果你在outputstream的外层套一层buffer,比如在SocketOutPutStream外层包一个BufferedOutPutStream,其内部会有自己的缓存,这个时候flush就有必要了,因为buffer相当于在jvm层做了一层缓存,直到调用flush函数,数据才会被写出。
进程在意外停止的时候,其关联的socket会关闭吗? 会关闭,在linux系统中,是会这样的。当进程意外中止或者被kill的时候,系统会直接调用相关socket的close函数,单方面关闭socket链接并且不等待对方关闭,会直接给对方发送RST包。
推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • ***byte(字节)根据长度转成kb(千字节)和mb(兆字节)**parambytes*return*publicstaticStringbytes2kb(longbytes){ ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 树莓派Linux基础(一):查看文件系统的命令行操作
    本文介绍了在树莓派上通过SSH服务使用命令行查看文件系统的操作,包括cd命令用于变更目录、pwd命令用于显示当前目录位置、ls命令用于显示文件和目录列表。详细讲解了这些命令的使用方法和注意事项。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
戴安娜DianaKok
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有