C#实现TFTP客户端

1、文件结构
在这里插入图片描述
2、TftpConfig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TftpTest
{
    public class TftpConfig
    {
    }
    /// <summary>
    /// 模式
    /// </summary>
    public enum Modes
    {
        NETASCII = 0,   //ASCII
        OCTET = 1       //二进制
    }
    /// <summary>
    /// 操作码
    /// </summary>
    public enum OpCodes
    {
        RRQ = 1,    // 读请求
        WRQ = 2,    // 写请求
        DATA = 3,   // 数据
        ACK = 4,    // Acknowledge
        ERROR = 5,  // 错误
        OACK = 6    // Option Acknowledge
    }
    public enum TransferType
    {
        Get,
        Put
    }
    public struct TransferOptions
    {
        private TransferType _action;

        public TransferType Action
        {
            get { return _action; }
            set { _action = value; }
        }

        private string _localFilename;

        public string LocalFilename
        {
            get { return _localFilename; }
            set { _localFilename = value; }
        }

        private string _remoteFilename;

        public string RemoteFilename
        {
            get { return _remoteFilename; }
            set { _remoteFilename = value; }
        }

        private string _host;

        public string Host
        {
            get { return _host; }
            set { _host = value; }
        }
    }
}

3、ErrorPacket.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TftpTest
{
    public class ErrorPacket
    {
        short _code;

        public short Code
        {
            get { return _code; }
            set { _code = value; }
        }

        string _message;

        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }

        public ErrorPacket(short Code, string Message)
        {
            Code = _code;
            Message = _message;
        }
    }
}

4、PacketBuilder.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TftpTest
{
    public class PacketBuilder
    {
        public byte[] Request(OpCodes OpCode, string RemoteFileName,
            Modes Mode, int BlockSize, long TransferSize, int Timeout)
        {
            // Request packet structure
            // -----------------------------------------------------------------------------
            // |OpCode|FileName|0|Mode|0|BlkSize|0|BSVal|0|TSize|0|TSVal|0|Timeout|0|TVal|0|
            // -----------------------------------------------------------------------------
            int len;

            string packetStr = "";
            string mode = Mode.ToString().ToLower();
            string blockSize = BlockSize.ToString();
            string nullChar = "\0";

            byte[] packet;

            // Create packet as a string
            switch (OpCode)
            {
                case OpCodes.RRQ:
                    packetStr = nullChar + (char)1;
                    break;
                case OpCodes.WRQ:
                    packetStr = nullChar + (char)2;
                    break;
            }

            packetStr += RemoteFileName + nullChar + mode + nullChar + "blksize" +
                nullChar + BlockSize.ToString() + nullChar + "tsize" + nullChar +
                TransferSize.ToString() + nullChar + "timeout" + nullChar +
                Timeout.ToString() + nullChar;

            len = packetStr.Length;
            packet = new byte[len];

            // Encode packet as ASCII bytes
            packet = System.Text.Encoding.ASCII.GetBytes(packetStr);
            return packet;
        }

        public byte[] Ack(int Block1, int Block2)
        {
            // ACK packet structure
            // ----------
            // |04|Block|
            // ----------
            byte[] packet = new byte[4];
            packet[0] = 0;
            packet[1] = (byte)OpCodes.ACK;
            packet[2] = (byte)Block1;
            packet[3] = (byte)Block2;
            return packet;
        }

        public byte[] Data(byte[] SendData, int Block1, int Block2)
        {
            // DATA packet structure
            // ----------
            // |03|Block|
            // ----------
            byte[] packet = new byte[SendData.Length + 4];
            //packet[0] = 0;
            packet[1] = (byte)OpCodes.DATA;
            packet[2] = (byte)Block1;
            packet[3] = (byte)Block2;
            for (int h = 4; h < SendData.Length + 4; h++)
            {
                packet[h] = SendData[h - 4];
            }
            return packet;
        }

        public int[] IncrementBock(byte[] ReceivedData, int[] Block)
        {
            if (ReceivedData[3] == 255)
            {
                if (ReceivedData[2] < 255)
                {
                    Block[0] = (int)ReceivedData[2] + 1; Block[1] = 0;
                }
                else
                {
                    Block[0] = 0; Block[1] = 0;
                }
            }
            else
            {
                Block[1] = (int)ReceivedData[3] + 1;
            }
            return Block;
        }
    }
}

5、PacketReader.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TftpTest
{
    public class PacketReader
    {
        public OpCodes ReadOpCode(byte[] ReceivedData)
        {
            return (OpCodes)ReceivedData[1];
        }

        public int ReadTransferSize(byte[] ReceivedData)
        {
            int h, tSize = 0;
            string searchStr, decPacket = Encoding.ASCII.GetString(ReceivedData);
            char[] splitChar = { '\0' };
            string[] splitPacket = decPacket.Split(splitChar);

            for (h = 0; h < splitPacket.Length - 1; h++)
            {
                searchStr = splitPacket[h].ToLower();
                if (searchStr == "tsize")
                {
                    tSize = int.Parse(splitPacket[h + 1]);
                }
            }
            return tSize;
        }

        public ErrorPacket ReadError(byte[] ReceivedData)
        {
            string codeStr = ReceivedData[2].ToString() + ReceivedData[3].ToString();

            short code = short.Parse(codeStr);
            string message = "";

            for (int h = 4; h < ReceivedData.Length; h++)
            {
                if (ReceivedData[h] == 0)
                    break;

                message += (char)ReceivedData[h];
            }

            return new ErrorPacket(code, message);
        }

        public bool CompareBlocks(byte[] SentData, byte[] ReceivedData)
        {
            if (ReceivedData[2] == SentData[2] &&
                ReceivedData[3] == SentData[3])
                return true;

            return false;
        }
    }
}

6、TftpClient.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace TftpTest
{
    public class TftpClient
    {
        // 委托
        public delegate void ConnectedHandler();
        public delegate void TransferringHandler(long BytesTransferred, long BytesTotal);
        public delegate void TransferFailedHandler(short ErrorCode, string ErrorMessage);
        public delegate void TransferFinishedHandler();
        public delegate void DisconnectedHandler();

        // 事件
        public event ConnectedHandler Connected;
        public event TransferringHandler Transferring;
        public event TransferFailedHandler TransferFailed;
        public event TransferFinishedHandler TransferFinished;
        public event DisconnectedHandler Disconnected;

        private string _host;
        [Description("主机")]
        public string Host
        {
            get { return _host; }
            set { _host = value; }
        }

        private Modes _mode = Modes.OCTET;
        [Description("模式")]
        public Modes Mode
        {
            get { return _mode; }
            set { _mode = value; }
        }

        private int _blockSIze = 512;
        [Description("块大小")]
        public int BlockSize
        {
            get { return _blockSIze; }
            set { _blockSIze = value; }
        }

        private int _timeout = 10;
        [Description("溢出时间")]
        public int Timeout
        {
            get { return _timeout; }
            set { _timeout = value; }
        }

        PacketReader _packetReader = new PacketReader();

        PacketBuilder _packetBuilder = new PacketBuilder();

        public bool Get(string localFile, string RemoteFile, string Host)
        {
            return Get(localFile, RemoteFile, Host, Mode, BlockSize, Timeout);
        }

        public bool Put(string localFile, string RemoteFile, string Host)
        {
            return Put(localFile, RemoteFile, Host, Mode, BlockSize, Timeout);
        }

        public bool Get(string LocalFile, string RemoteFile, string Host,
            Modes Mode, int BlockSize, int Timeout)
        {
            int recvLen, remoteFileSize = 0, buffer = BlockSize + 4;
            long bytesReceived = 0;

            BinaryWriter BWriter = new BinaryWriter(File.Open(LocalFile, FileMode.Create));

            OpCodes opCode = new OpCodes();

            IPHostEntry hInfo = Dns.GetHostEntry(Host);
            IPAddress address = hInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(address, 69);
            EndPoint localEP = (remoteEP);
            Socket UDPSock = new Socket
                (remoteEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            // Create initial request and buffer for response
            byte[] sendData = _packetBuilder.Request(OpCodes.RRQ,
                RemoteFile, Mode, BlockSize, 0, Timeout);
            byte[] recvData = new byte[BlockSize + 4];

            UDPSock.ReceiveTimeout = Timeout * 1000;

            // Send request and wait for response
            UDPSock.SendTo(sendData, remoteEP);
            recvLen = UDPSock.ReceiveFrom(recvData, ref localEP);

            // Get TID
            remoteEP.Port = ((IPEndPoint)localEP).Port;

            // Invoke connected event
            Connected.Invoke();

            while (true)
            {
                // Read opcode
                opCode = _packetReader.ReadOpCode(recvData);

                // DATA packet
                if (opCode == OpCodes.DATA)
                {
                    bytesReceived += recvLen - 4;



                    // Invoke Transferring Event
                    Transferring.Invoke(bytesReceived, remoteFileSize);

                    for (int h = 4; h < recvLen; h++)
                    {
                        BWriter.Write(recvData[h]);
                    }

                    sendData = _packetBuilder.Ack(recvData[2], recvData[3]);

                    // Check if this packet is the last
                    if (recvLen < buffer)
                    {
                        // Send final ACK
                        UDPSock.SendTo(sendData, remoteEP);

                        // Invoked TransferFinished Event
                        TransferFinished.Invoke();

                        break;
                    }
                }

                // OACK packet
                else if (opCode == OpCodes.OACK)
                {
                    remoteFileSize = _packetReader.ReadTransferSize(recvData);
                    sendData = _packetBuilder.Ack(0, 0);
                }

                // ERROR packet
                else if (opCode == OpCodes.ERROR)
                {
                    ErrorPacket transferError = _packetReader.ReadError(recvData);
                    TransferFailed.Invoke(transferError.Code, transferError.Message);

                    break;
                }

                // Send next packet
                UDPSock.SendTo(sendData, remoteEP);
                recvLen = UDPSock.ReceiveFrom(recvData, ref localEP);
                remoteEP.Port = ((IPEndPoint)localEP).Port;
            }

            BWriter.Close();
            UDPSock.Close();

            // Invoke Disconnected Event
            Disconnected.Invoke();
            return true;
        }

        public bool Put(string LocalFile, string RemoteFile, string Host,
            Modes Mode, int BlockSize, int Timeout)
        {
            int[] block = new int[2];
            int bufferSize = BlockSize;
            long fileSize, bytesSent = 0;

            BinaryReader BReader = new BinaryReader(File.Open(LocalFile, FileMode.Open));
            FileInfo sendFile = new FileInfo(LocalFile);

            OpCodes opCode = new OpCodes();

            IPHostEntry hostInfo = Dns.GetHostEntry(Host);
            IPAddress address = hostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(address, 69);
            EndPoint localEP = (remoteEP);
            Socket UDPSock = new Socket
                (remoteEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            // Retrieve filesize for tsize option
            fileSize = sendFile.Length;

            // Create initial request and buffer for response
            byte[] sendData = _packetBuilder.Request(OpCodes.WRQ,
                RemoteFile, Mode, BlockSize, fileSize, Timeout);
            byte[] recvData = new byte[bufferSize];

            UDPSock.ReceiveTimeout = Timeout * 1000;

            // Send request and wait for response
            UDPSock.SendTo(sendData, remoteEP);
            UDPSock.ReceiveFrom(recvData, ref localEP);

            //Get TID
            remoteEP.Port = ((IPEndPoint)localEP).Port;

            // Invoke Connected Event
            Connected.Invoke();

            while (true)
            {
                // Read opcode
                opCode = _packetReader.ReadOpCode(recvData);

                // ACK packet
                if (opCode == OpCodes.ACK)
                {
                    block = _packetBuilder.IncrementBock(recvData, block);

                    sendData = BReader.ReadBytes(bufferSize);
                    bytesSent += sendData.Length;

                    // Invoke Transferring Event
                    Transferring.Invoke(bytesSent, fileSize);

                    sendData = _packetBuilder.Data(sendData, block[0], block[1]);

                    // Check if this packet is the last
                    if (sendData.Length < bufferSize + 4)
                    {
                        // Send final data packet and wait for ack
                        while (true)
                        {
                            UDPSock.SendTo(sendData, remoteEP);
                            UDPSock.ReceiveFrom(recvData, ref localEP);
                            remoteEP.Port = ((IPEndPoint)localEP).Port;

                            // Check the blocks and break free if equal
                            if (_packetReader.CompareBlocks(sendData, recvData))
                                break;
                        }

                        // Invoke TransferFinished Event
                        TransferFinished.Invoke();
                        break;
                    }
                }

                // OACK packet
                else if (opCode == OpCodes.OACK)
                {
                    sendData = BReader.ReadBytes(bufferSize);
                    sendData = _packetBuilder.Data(sendData, 0, 1);
                    bytesSent += sendData.Length - 4;

                    // Invoke Transferring Event
                    Transferring.Invoke(bytesSent, fileSize);

                    if (fileSize == 0)
                    {
                        // Invoke TransferFinished Event
                        TransferFinished.Invoke();
                        break;
                    }
                    else
                    {

                        // Check if this packet is the last
                        if (sendData.Length < bufferSize + 4)
                        {
                            // Send final data packet and wait for ack
                            while (true)
                            {
                                UDPSock.SendTo(sendData, remoteEP);
                                UDPSock.ReceiveFrom(recvData, ref localEP);
                                remoteEP.Port = ((IPEndPoint)localEP).Port;

                                // Check the blocks and break free if equal
                                if (_packetReader.CompareBlocks(sendData, recvData))
                                    break;
                            }
                            // Invoke TransferFinished Event
                            TransferFinished.Invoke();
                            break;
                        }
                    }
                }
                else if (opCode == OpCodes.ERROR)
                {
                    ErrorPacket transferError = _packetReader.ReadError(recvData);
                    TransferFailed.Invoke(transferError.Code, transferError.Message);
                    break;
                }

                // Send next packet
                UDPSock.SendTo(sendData, remoteEP);
                UDPSock.ReceiveFrom(recvData, ref localEP);
                remoteEP.Port = ((IPEndPoint)localEP).Port;
            }
            BReader.Close();
            UDPSock.Close();

            // Invoke Disconnected Event
            Disconnected.Invoke();

            return true;
        }
    }
}

7、MainForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace TftpTest
{
    public partial class MainForm : Form
    {
        private TftpClient tftpClient = new TftpClient();
        private delegate void ProgressBarDelegate(int Maximum, int Value);
        private delegate void TransferButtonDelegate(bool Enabled);

        public MainForm()
        {
            InitializeComponent();
            tftpClient.Connected += new TftpClient.ConnectedHandler(TftpClient_Connected);
            tftpClient.Transferring += new TftpClient.TransferringHandler(TftpClient_Transferring);
            tftpClient.TransferFailed += new TftpClient.TransferFailedHandler(TftpClient_TransferFailed);
            tftpClient.TransferFinished += new TftpClient.TransferFinishedHandler(TftpClient_TransferFinished);
            tftpClient.Disconnected += new TftpClient.DisconnectedHandler(TftpClient_Disconnected);
        }

        private void TftpClient_Connected()
        {

            TransferButtonDelegate tBtnDel = new TransferButtonDelegate(TransferBtnDelegateFunction);
            btnTest.Invoke(tBtnDel, false);

            Console.WriteLine("Connected");
        }

        private void TransferBtnDelegateFunction(bool Enabled)
        {
            lock (btnTest)
            {
                btnTest.Enabled = Enabled;
            }
        }

        private void TftpClient_Transferring(long BytesTransferred, long BytesTotal)
        {
            if (BytesTotal != 0)
            {
                ProgressBarDelegate progressBarDel = new ProgressBarDelegate(ProgressBarDelegateFunction);
                progressBarTftp.Invoke(progressBarDel,
                    new object[2] { (int)(BytesTotal / 10), (int)(BytesTransferred / 10) });

                Console.Write("{0}/{1} Bytes Transferred\r", BytesTransferred, BytesTotal);
            }
            else
                Console.Write(".");
        }

        private void ProgressBarDelegateFunction(int Maximum, int Value)
        {
            lock (progressBarTftp)
            {
                try
                {

                    progressBarTftp.Maximum = Maximum;
                    progressBarTftp.Value = Value;
                }
                catch (Exception e) { Console.WriteLine(e.ToString()); }
            }
        }

        private void TftpClient_TransferFailed(short ErrorCode, string ErrorMessage)
        {
            Console.WriteLine("Error {0}: {1}", ErrorCode, ErrorMessage);
        }

        private void TftpClient_TransferFinished()
        {
            ProgressBarDelegate progressBarDel = new ProgressBarDelegate(ProgressBarDelegateFunction);
            progressBarTftp.Invoke(progressBarDel, new object[2] { 0, 0 });

            Console.WriteLine("\nTransfer Finished");

            MessageBox.Show("Transfer Complete", "TFTP Client",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void TftpClient_Disconnected()
        {
            TransferButtonDelegate tBtnDel = new TransferButtonDelegate(TransferBtnDelegateFunction);
            btnTest.Invoke(tBtnDel, true);

            Console.WriteLine("Disconnected\n");
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            progressBarTftp.Value = 0;

            TransferOptions tOptions = new TransferOptions();
            //tOptions.LocalFilename = "D:\\Project\\QDRP3\\Sw\\QDRP\\QDRP\\bin\\Debug\\Case\\PLBIN.bin";
            tOptions.LocalFilename = "F:\\Test\\PLBIN.bin";
            tOptions.RemoteFilename = "PLBIN.bin";
            tOptions.Host = "10.11.9.62";
            //tOptions.Action = getRadio.Checked == true ? TransferType.Get : TransferType.Put;
            tOptions.Action = TransferType.Get;

            Thread tThread = new Thread((ParameterizedThreadStart)delegate (object ScanOptions)
            {
                TransferOptions options = (TransferOptions)ScanOptions;
                if (options.Action == TransferType.Get)
                    tftpClient.Get(options.LocalFilename,options.RemoteFilename,options.Host);
                else
                    tftpClient.Put(options.LocalFilename, options.RemoteFilename, options.Host);
            });
            tThread.IsBackground = true;
            tThread.Start(tOptions);
        }
    }
}

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

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

相关文章

大模型都在用的:旋转位置编码

写在前面 这篇文章提到了绝对位置编码和相对位置编码&#xff0c;但是他们都有局限性&#xff0c;比如绝对位置编码不能直接表征token的相对位置关系&#xff1b;相对位置编码过于复杂&#xff0c;影响效率。于是诞生了一种用绝对位置编码的方式实现相对位置编码的编码方式——…

LS2K1000LA基础教程

基于LS2K1000LA的基础教程 by 南京工业大学 孙冬梅 于 2024.4.25 文章目录 基于LS2K1000LA的基础教程一、目的二、平台1.硬件平台2.软件平台 三、测试0.开发板开机及编译器配置0.1 开发板控制台0.2 虚拟机编译器配置 1. 简单应用编程1.helloworld.c2. fileio 文件操作3.proce…

Scrapy 爬虫教程:从原理到实战

Scrapy 爬虫教程&#xff1a;从原理到实战 一、Scrapy框架简介 Scrapy是一个由Python开发的高效网络爬虫框架&#xff0c;用于从网站上抓取数据并提取结构化信息。它采用异步IO处理请求&#xff0c;能够同时发送多个请求&#xff0c;极大地提高了爬虫效率。 二、Scrapy运行原…

入坑 Java

原文&#xff1a;https://blog.iyatt.com/?p11305 前言 今天&#xff08;2023.8.31&#xff09;有个学长问我接不接一个单子&#xff0c;奈何没学过 Java&#xff0c;本来不打算接的。只是报酬感觉还不错&#xff0c;就接了。 要求的完成时间是在10月初&#xff0c;总共有一…

Spring Boost + Elasticsearch 实现检索查询

需求&#xff1a;对“昵称”进行“全文检索查询”&#xff0c;对“账号”进行“精确查询”。 认识 Elasticsearch 1. ES 的倒排索引 正向索引 对 id 进行检索速度很快。对其他字段即使加了索引&#xff0c;只能满足精确查询。模糊查询时&#xff0c;逐条数据扫描&#xff0c…

编译原理实验课

本人没咋学编译原理&#xff0c;能力有限&#xff0c;写的不好轻点喷&#xff0c;大佬路过的话&#xff0c;那你就路过就好 东大编译原理实验课原题&#xff0c;22年 1. 基本题&#xff1a;简单的扫描器设计 【问题描述】 熟悉并实现一个简单的扫描器&#xff0c;设计扫描器…

C++ | Leetcode C++题解之第49题字母异位词分组

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<string>> groupAnagrams(vector<string>& strs) {// 自定义对 array<int, 26> 类型的哈希函数auto arrayHash [fn hash<int>{}] (const array<int, 26>&…

黑马点评(十二) -- UV统计

一 . UV统计-HyperLogLog 首先我们搞懂两个概念&#xff1a; UV&#xff1a;全称Unique Visitor&#xff0c;也叫独立访客量&#xff0c;是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站&#xff0c;只记录1次。 PV&#xff1a;全称Page View&…

linux权限维持(四)

6.inetd服务后门 inetd 是一个监听外部网络请求 ( 就是一个 socket) 的系统守护进程&#xff0c;默认情况下为 13 端口。当 inetd 接收到 一个外部请求后&#xff0c;它会根据这个请求到自己的配置文件中去找到实际处理它的程序&#xff0c;然后再把接收到的 这个socket 交给那…

机器学习 -- 分类问题

场景 探讨了一个回归任务——预测住房价格&#xff0c;用到了线性回归、决策树以及随机森林等各种算法。本次中我们将把注意力转向分类系统。我们曾经对MNIST进行了分类任务&#xff0c;这次我们重新回到这里&#xff0c;细致的再来一次。 开始 获取数据 Scikit-Learn提供了…

力扣爆刷第127天之动态规划五连刷(整数拆分、一和零、背包)

力扣爆刷第127天之动态规划五连刷&#xff08;整数拆分、一和零、背包&#xff09; 文章目录 力扣爆刷第127天之动态规划五连刷&#xff08;整数拆分、一和零、背包&#xff09;关于0 1 背包问题的总结01背包遍历顺序&#xff1a;完全背包遍历顺序&#xff1a; 一、343. 整数拆…

Lock-It for Mac(应用程序加密工具)

OSXBytes Lock-It for Mac是一款功能强大的应用程序加密工具&#xff0c;专为Mac用户设计。该软件具有多种功能&#xff0c;旨在保护用户的隐私和数据安全。 Lock-It for Mac v1.3.0激活版下载 首先&#xff0c;Lock-It for Mac能够完全隐藏应用程序&#xff0c;使其不易被他人…

【Pytorch】(十四)C++ 加载TorchScript 模型

文章目录 &#xff08;十四&#xff09;C 加载TorchScript 模型Step 1: 将PyTorch模型转换为TorchScriptStep 2: 将TorchScript序列化为文件Step 3: C程序中加载TorchScript模型Step 4: C程序中运行TorchScript模型 【Pytorch】&#xff08;十三&#xff09;PyTorch模型部署: T…

平衡二叉树、红黑树、B树、B+树

Tree 1、前言2、平衡二叉树和红黑树3、B树和B树3.1、B树的构建3.2、B树和B树的区别3.3、数据的存储方式 1、前言 本文侧重在理论方面对平衡二叉树、红黑树、B树和B树的各方面性能进行比较。不涉及编程方面的实现。而关于于平衡二叉树在C中的实现&#xff0c;我的上一篇文章平衡…

Nginx基本使用 反向代理与负载均衡

什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。 其特点是占有内存少&#xff0c;并发能力强&#xff0c;nginx的并发能力在同类型的网页服务器中表现较好&#xff0c;而且几乎可以做到7*24不间断运行&#xff0c;即使运行数个月也不需要重新启动。 …

操作系统安全:Linux安全审计,Linux日志详解

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

【树莓派】yolov5 Lite,目标检测,树莓派4B,推理v5lite-e_end2end.onnx,摄像头实时目标检测

文章目录 YOLOv5 Lite: 在树莓派上轻松运行目标检测1. 环境配置2. 克隆项目3. 安装依赖项4. 下载模型权重5. 理解end2end的含义6. 示例推理7. 文件介绍8. 把文件弄到树莓派4B执行9. 进一步尝试fp16的onnx&#xff08;行不通&#xff09;10. 视频流检测 这里有大概的环境配置&am…

80个在线小游戏源码

源码简介 搭建80个在线小游戏网站源码&#xff0c;解压即可食用&#xff0c;支持在本地浏览器打开。 安装教程 纯HTML&#xff0c;直接将压缩包上传网站目录解压即可 首页截图 源码下载 80个在线小游戏源码-小8源码屋

Mac虚拟机装Windows Mac环境安装Win虚拟机教程 macbookpro安装windows虚拟机

在如今多元的数字时代&#xff0c;我们经常需要在不同的操作系统环境下进行工作和学习。而对于Mac用户来说&#xff0c;有时候需要在自己的电脑上安装Windows操作系统&#xff0c;以体验更多软件及功能&#xff0c;而在Mac安装Windows虚拟机是常用的一种操作。下面就来看看Mac虚…

前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统(LIMS)成品源码 B/S架构

前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统&#xff08;LIMS&#xff09;成品源码 B/S架构 LIMS实验室管理系统 发展历史 实验室信息管理系统(LIMS)&#xff0c;就是指通过计算机网络技术对实验的各种信息进行管理的计算机软、硬件系统。也就是将计算机网络技术与现…