网络协议

一、 网络协议

1.1 网络模型

1.1.1 OSI七层模型

       开放系统互联参考模型(Open System Interconnect)是国际标准化组织(ISO)制订的一个用于计算机或通信系统间互联的标准体系。采用七层结构,自下而上依次为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

1.1.2 TCP/IP模型

       是一组用于实现网络互连的通信协议。Internet网络体系结构以TCP/IP为核心。采用四层结构,自下而上依次为:链路层、网络层、传输层、应用层。

       两个模型之间的对应关系:
在这里插入图片描述

       TCP/IP协议族
        TCP/IP协议簇是Internet的基础,也是当今最流行的组网形式。TCP/IP是一组协议的代名词,包括许多别的协议,组成了TCP/IP协议簇。
在这里插入图片描述

1.2 TCP

       TCP是为了在不可靠的互联网络上提供一种面向连接的、可靠的、基于字节流的传输层通信协议。

1.2.1 TCP的三次握手(建立连接)

       建立一个TCP连接时需要客户端和服务端总共发送三次数据包以确认连接的建立。

       三次握手过程:
       1) 客户端发送SYN(SYN=x)报文给服务端,进入SYN_SEND状态。
       2) 服务端收到SYN报文,回应一个SYN(SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
       3) 客户端收到服务端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态,完成三次握手。
在这里插入图片描述

       
       TCP三次握手的漏洞
       如果你一个客户端向服务端发送了SYN报文后突然死机或掉线,那么服务器在发送SYN+ACK报文后是无法收到客户端ACK报文的,这种情况下服务端一般会不停的重试,并等待一段时间(大约为30秒-2分钟)后丢弃未完成的链接。一个用户出现异常不是什么大问题,但如果一个攻击者发送大量伪造原IP地址的攻击报文到服务器,服务器将为了维护一个非常大的半连接队列而消耗更多的CPU和内存资源。服务器忙于处理伪造的TCP连接请求而无暇理睬客户的正常需求。这种情况称为服务器受到了SYN Flood攻击(SYN洪水攻击)。

解决方案:

  1. 缩短SYN无效时间
    过小的无效时间可能会影响到正常客户端连接,不建议使用。
  2. 延迟TCB分配
    一般第一次握手后,服务器会为该请求分配TCB(连接控制资源),通常需要200多字节。如果等到连接建立后再分配,可有效的减轻服务器资源的消耗。
  3. 防火墙
    防火墙在确认了连接的有效性后,才向内部的服务器(Listener)发起 SYN请求。

1.2.2 TCP四次挥手(连接终止)

       建立一个连接需要三次握手,而终止一个连接要经过四次挥手。这是由TCP的半关(half-close)造成的。

       具体过程如下:
       1) 客户端进程向服务端发送标志位是FIN的报文段,设置序列号为seq,此时,客户端进入FIN_WAIT_1状态,并且停止发送数据。
       2) 服务端收到客户端发送的FIN报文段,向客户端返回一个标志位为ACK(ack=seq+1)的报文段,服务器进入CLOSE_WAIT(关闭等待)状态。客户端收到服务器确认请求后,进入FIN_WAIT_2状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后数据)。
       3) 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文(FIN=1,ACK=seq+1),服务器进入LAST_ACK状态,等待客户端确认。
       4) 客户端收到服务端连接释放的报文后,发出确认报文,客户端进入TIME_WAIT状态。此时TCP连接还没释放,必须经过2MSL(最长报文寿命)的时间后,撤销TCB,进入CLOSED状态。服务端只要收到确认,立即进入CLOSED状态。
在这里插入图片描述

 
       TCP的可靠性
       在TCP中,当发送端的数据达到接收主机时,接收主机会发回确认应答(ACK)。如果发送端收到确认应答,说明数据已成功发送到接收主机。反之,如果一段时间内没有收到确认应答,发送端就认为数据丢失,进行重发。因此即使产生丢包,仍然能够保证数据到达接收主机,实现可靠传输。
未收到确认应答并不意味着数据丢失,也有可能接收方已经收到数据,但是确认应答数据在途中丢失,这种情况发送端会误以为接收方没有收到而重发数据。
       对于接收方来说,反复收到相同的数据是不可取的。为了对上层应用提供可靠传输,接收主机必须放弃重复的数据包。因此引入了序列号。
序列号是按照顺序给发送数据的每一个字节(8 位字节)都标上号码的编号。接收端查询接收数据 TCP 首部中的序列号和数据的长度,将自己下一步应该接收的序列号作为确认应答返送回去。通过序列号和确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,从而实现可靠传输。

       TCP中的滑动窗口
       滑动窗口是TCP流量控制的一种方法。
首先第一次发送数据的时候窗口大小是根据链路带宽的大小决定的,假设是3。接收方收到数据后会对数据进行确认(ACK),并告诉发送方下次希望收到的数据是多少。发送方收到确认后按照发送方希望的数据大小发送。

1.3 UDP

       UDP(用户数据协议,User Datagram Protocol)为应用程序提供了一种无需建立连接就可以发送数据包的方法。UDP是一个不可靠的协议。
       使用UDP的服务主要包括:视频音频等多媒体通信、限定于局域网等特定网络中的通信、广播通信等。

1.4 HTTP

       HTTP(超文本传输协议,Hyper Text Transfer Protocol)是用于万维网(www)客户端浏览器和服务器进行传输的协议。

       一次完整HTTP请求的7个过程
       1) 三次握手建立TCP连接。
       2) 客户端向服务器发送请求命令。
       3) 客户端发送请求头信息。
       4) 服务器应答。
       ;5) 服务器向客户端发送数据。
       ;6) 关闭TCP连接。

       HTTP协议报文结构
       请求报文结构:
在这里插入图片描述
在这里插入图片描述
       响应报文结构:

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

二、 JAVA原生网络编程

2.1 LINUX网络IO模型

       阻塞IO
       应用程序调用IO函数后阻塞,等待数据准备好。当数据准备好时,将数据从内核拷贝到用户空间,IO函数返回。
在这里插入图片描述

       非阻塞IO
       当应用程序调用IO函数后不会阻塞,如果没有数据会返回一个错误,应用程序反复调用IO函数,直到数据准备好。不断调用的过程会消耗大量的CPU资源,不推荐使用。
在这里插入图片描述

       IO多路复用
       IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题,此外poll、epoll都是这种模型。在该种模式下,用户首先将需要进行IO操作的 socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起 read请求,读取数据并继续执行。从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理 多个socket的IO请求。用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处 理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。
在这里插入图片描述

       信号驱动IO
       套接口进行信号驱动IO,并安装一个信号处理函数,进程继续运行而不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号函数调用IO函数处理数据。
在这里插入图片描述

       异步IO
       当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。
       LINUX底层使用epoll实现,是伪异步。
在这里插入图片描述

       5种IO模型比较:
在这里插入图片描述

       select、poll、epoll区别

  1. 打开的最大连接数不同。
    select最小,底层使用数组实现。
    poll最大,没有限制。底层使用链表实现。
    epoll非常大,有限制。1G内存支持10万个连接。
  2. IO效率不同。
    FD(文件描述符)增加后带来的IO效率问题。
    因为每次调用时都会对连接进行遍历,所以随着 FD(文件描述符) 的增加select和poll性能呈线性下降。而epoll只关注活跃连接,所以在活跃连接较少的情况下,性能高于前两者。
  3. 消息(报文)传递方式不同
    select、poll:数据需要从内核空间传输到用户空间。
    epoll:通过内核和用户空间共享一块内存实现的。

2.2 BIO

       传统的BIO通信模型:服务端通常由一个独立Acceptor线程负责监听客户端连接,收到客户端请求后为每个客户端创建一个新的线程进行处理,处理完成后通过输出流返回应答给客户端。该模型最大的问题是当请求增多,线程数量增加,系统性能急剧下降。可以使用线程池进行改进。

       服务端代码:

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress(8888));

        while (true) {
            new Thread(new Task(serverSocket.accept())).start();
        }
    }

    static class Task implements Runnable {

        private Socket socket;

        Task(Socket socket) {
            this.socket = socket;
        }

        @SneakyThrows
        @Override
        public void run() {
            ObjectOutputStream outputStream = null;
            ObjectInputStream inputStream = null;


            try {
                inputStream = new ObjectInputStream(socket.getInputStream());
                String name = inputStream.readUTF();

                System.out.println("收到客户端发来的信息....." + name);

                outputStream = new ObjectOutputStream(socket.getOutputStream());
                outputStream.writeUTF("Hello," + name);
                outputStream.flush();

            } finally {
                if (inputStream != null) inputStream.close();
                if (outputStream != null) outputStream.close();
            }
        }
    }
}

       客户端代码:

public class Client {

    private final static String IP = "127.0.0.1";
    private final static int PORT = 8888;

    public static void main(String[] args) throws IOException {


        Socket socket = new Socket();
        socket.connect(new InetSocketAddress(IP, PORT));

        ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());

        outputStream.writeUTF("hello");

        outputStream.flush();

        ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
        String context = inputStream.readUTF();
        System.out.println("收到了服务器回复的消息..." + context);

        outputStream.close();
        inputStream.close();
        socket.close();
    }
}

2.3 NIO

2.3.1 NIO与BIO的区别

  1. NIO是面向缓冲区的,BIO是面向流的。
  2. NIO是非阻塞的,BIO是阻塞的。
  3. NIO使用Selectors(选择器)。

2.3.2 NIO主要由三个核心部分组成

  1. Selector(选择器) 应用程序将向 Selector 对象注册需要它关注的 Channel,以及具体的某一个Channel会对哪些 IO 事件感兴趣。Selector 中也会维护一个“已经注册的 Channel” 的容器。
  2. Channel(通道)
    应用程序和操作系统交互事件、传递内容的渠道。应用程序可以通过通道读取数据,也可以通过通道向操作系统写数据。
    ServerSocketChannel ScoketChannel
  3. Buffer(缓冲区)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/296098.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pytest安装失败,报错Could not find a version that satisfies the requirement pytest

问题 安装pytest失败,尝试使用的命令有 pip install pytest pip3 install pytest pip install -U pytest pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple但是都会报同样的错: 解决方案 发现可能是挂了梯子的原因,关掉…

听GPT 讲Rust源代码--compiler(15)

File: rust/compiler/rustc_arena/src/lib.rs 在Rust源代码中&#xff0c;rustc_arena/src/lib.rs文件定义了TypedArena&#xff0c;ArenaChunk&#xff0c;DroplessArena和Arena结构体&#xff0c;以及一些与内存分配和容器操作相关的函数。 cold_path<F: FnOnce,drop,new,…

Simply简洁博客主题源码 | EmlogPro主题模版

Simply是一款简约风格的Emlog博客模板&#xff0c;响应式布局、界面简单大方&#xff0c;实用性强&#xff01; 支持夜间模式&#xff0c;采用localStorage存储配置。IOS系统下支持随系统自动切换浅/深色模式。 文章页支持显示文章字数及阅读时间。 支持http/https 响应式主…

计算机进入BIOS - Win/Linux

计算机进入BIOS - Win/Linux 快捷键方法&#xff08;通用&#xff09;Win系统方法Linux系统方法 快捷键方法&#xff08;通用&#xff09; 此方法为通用方法&#xff0c;适用于任何型号的计算机&#xff0c;包括台式机和笔记本&#xff0c;也包括Win系统和Linux系统。 进入BI…

package-info.java delete

package-info.java delete

解决Gitee每次push都需要输入用户名和密码

其实很简单&#xff0c;只需要使用命令 git config --global credential.helper store 在你下次push时只需要再输入一次用户名和密码&#xff0c;电脑就会保存下来&#xff0c;之后就无需进行输入了。

宏基因组序列分析工具EukRep

文章&#xff1a;Genome-reconstruction for eukaryotes from complex natural microbial communities | bioRxiv 仓库&#xff1a;patrickwest/EukRep: Classification of Eukaryotic and Prokaryotic sequences from metagenomic datasets (github.com) 推荐使用conda进行安…

揭开 JavaScript 作用域的神秘面纱(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Mac 安装Nginx教程

Nginx官网 Nginx官网英文 1.在终端输入brew search nginx 命令检查nginx是否安装了 2. 安装命令&#xff1a;brew install nginx 3. 查看Nginx信息命令brew info nginx 4. 启动 nginx方式&#xff1a;在终端里输入 nginx 5.查看 nginx 是否启动成功 在浏览器中访问http://l…

通过使用别名让 SQL 更简短-数据库教程shulanxt.com-帆软软件有限公司

MySQL视频教程导航 https://www.shulanxt.com/database/mysqlvideo/p1 SQL 别名 SQL 别名 通过使用 SQL&#xff0c;可以为表名称或列名称指定别名。 基本上&#xff0c;创建别名是为了让列名称的可读性更强。 列的 SQL 别名语法 SELECT column_name AS alias_name FROM …

【java】期末复习知识点

简单不先于复杂&#xff0c;而是在复杂之后。 文章目录 填空题封装包主类开发过程的改变interfaceabstract class访问控制关键字继承多态object 类Java I/O(输入/输出)异常线程和进程创建线程的两种基本方法 编程题Hello World编写Swing程序&#xff0c;显示一个空白窗口 填空题…

Huggy Lingo: 利用机器学习改进 Hugging Face Hub 上的语言元数据

太长不看版: Hub 上有不少数据集没有语言元数据&#xff0c;我们用机器学习来检测其语言&#xff0c;并使用 librarian-bots 自动向这些数据集提 PR 以添加其语言元数据。 Hugging Face Hub 已成为社区共享机器学习模型、数据集以及应用的存储库。随着 Hub 上的数据集越来越多&…

【AI视野·今日Sound 声学论文速览 第三十八期】Mon, 1 Jan 2024

AI视野今日CS.Sound 声学论文速览 Mon, 1 Jan 2024 Totally 5 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers The Arrow of Time in Music -- Revisiting the Temporal Structure of Music with Distinguishability and Unique Orientability as the …

案例093:基于微信小程序的南宁周边乡村游设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【CMake】1. VSCode 开发环境安装与运行

CMake 示例工程代码 https://github.com/LABELNET/cmake-simple 插件 使用 VSCode 开发C项目&#xff0c;安装 CMake 插件 CMakeCMake ToolsCMake Language Support &#xff08;建议&#xff0c;语法提示) 1. 配置 CMake Language Support , Windows 配置 donet 环境 这…

nginx连接数和性能优化

目录 一&#xff1a;介绍 二&#xff1a;优化配置 三&#xff1a;其他优化策略 一&#xff1a;介绍 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;具有许多用于优化连接数和性能的配置选项。以下是一些关键的配置和优化建议&#xff1a; 1&#xff1a;worker_proc…

Fast DDS 官方--C++ API Reference

Fast DDS 官方--C API Reference 1 介绍2 接口2.1 DDS DCPS PIM2.1.1 Core2.1.1.1 Entity 【基类】2.1.1.2 DomainEntity2.1.1.3 Policy 【枚举】2.1.1.3.1 DataRepresentationId2.1.1.3.2 DataRepresentationQosPolicy2.1.1.3.3 DataSharingQosPolicy2.1.1.3.4 DataSharingKin…

Spark MLlib简介与机器学习流程

在大数据领域&#xff0c;机器学习是一个关键的应用领域&#xff0c;可以用于从海量数据中提取有价值的信息和模式。Apache Spark MLlib是一个强大的机器学习库&#xff0c;可以在分布式大数据处理环境中进行机器学习任务。本文将深入介绍Spark MLlib的基本概念、机器学习流程以…

集合-及其各种特征详解

集合 概念&#xff1a;是提供一种存储空间 可变 的存储模型&#xff0c;存储的数据容量可以发生改变。&#xff08;也就是集合容量不固定&#xff09; 集合关系图 绿色的代表接口&#xff0c;蓝色的代表接口的实现类 单列集合 Collection(接口) 概述&#xff1a;单列集合的…

SSH 密钥身份验证和管理

安全外壳协议&#xff08;Security Shell Protocol&#xff09;是一种应用于计算机网络的安全通信协议&#xff0c;其提供的服务可用于保护网络上的连接和数据传输安全性&#xff0c;其核心思想是为网络上的两台计算机之间搭建一个安全的外壳&#xff0c;以保护数据传输的安全性…
最新文章