Linux C/C++ 学习笔记(七):DNS协议与请求

news2025/8/7 23:14:03

本文部分内容参考Linux C/C++ 开发(学习笔记九 ):DNS协议与请求的实现_菊头蝙蝠的博客-CSDN博客_struct dns

一、DNS的介绍

   域名系统(英文:Domain Name System,缩写:DNS的作用是将人类可读的域名 (如,www.example.com) 转换为机器可读的 IP 地址(如,192.0.2.44)

DNS的分层 

   域名系统是分层次的。在域名系统的层次结构中,各种域名都隶属于域名系统根域的下级。域名的第一级是顶级域,它包括通用顶级域,例如 .com.net .org;以及国家和 地区顶级域,例如 .us.cn .tk。顶级域名下一层是二级域名,一级一级地往下。这 些域名向人们提供注册服务,人们可以用它创建公开的互联网资源或运行网站。顶级域名的管理服务由对应的域名注册管理机构(域名注册局)负责,注册服务通常由域名注册商负责。

DNS服务类型

授权型DNS——一种授权型DNS服务提供一种更新机制,供开发人员用于管理其公用DNS名称。然后,它响应DNS查询,将域名转换为IP地址,以便计算机可以相互通信。授权型DNS对域有最终授权且负责提供递归型DNS服务器对IP地址信息的响应。阿里云是一种授权型DNS系统。

递归型DNS——客户端通常不会对授权型DNS服务直接进行查询。而是通常连接到称为解析程序的其他DNS服务,或递归型DNS服务。递归型DNS服务就像是旅馆的门童:尽管没有任何自身的DNS记录,但是可充当代表您获得DNS信息的中间程序。如果递归型DNS拥有已缓存或存储一段时间的DNS参考,那么它会通过提供源或IP信息来响应DNS查询。如果没有,则它会将查询传递到一个或多个授权型DNS服务器以查找信息。

记录类型

  DNS server内的每一个网域都有自己的档案,这个档案一般会称为区域档案,如”named.ca”或”named.local” 档案…等等。 区域档案是由多个记录组成的,每一个记录称为资源记录(Resource Record,简称RR)。 当在设定DNS名称解析、反向解析及其他的管理目的时,需要使用不同类型的RR,底下将介绍常用的RR类型及表示法。

NS 记录(域名服务) 指定解析域名或子域名的 DNS 服务器。
MX 记录(邮件交换) 指定接收信息的邮件服务器。

A 记录(地址) 指定域名对应的 IPv4 地址记录。

AAAA 记录(地址) 指定域名对应的 IPv6 地址记录。

CNAME (规范) 一个域名映射到另一个域名或 CNAME 记录( baidu.com 指向
www.baidu.com )或映射到一个 A 记录。

 PTR 记录(反向记录) ─ PTR 记录用于定义与 IP 地址相关联的名称。 PTR 记录 是 A AAAA 记录的逆。 PTR 记录是唯一的,因为它们以 .arpa 根开始并被委派 给 IP 地址的所有者。(反向DNS查找反向DNS解析(rDNS)是查询域名系统(DNS)来确定IP地址关联的域名的技术——通常的“转发”的反向DNS查找域名的IP地址。反向DNS查询的过程使用PTR记录。互联网的反向DNS数据库植根于 .arpa 顶级域名。

域名解析

 主机名到IP地址映射有两种方式:

静态映射 - 在本机上配置域名和 IP 的映射,旨在本机上使用。 Windows Linux 的 hosts 文件中的内容就属于静态映射
动态映射 - 建立一套域名解析系统( DNS ),只在专门的 DNS 服务器上配置主机到IP 地址的映射,网络上需要使用主机名通信的设备,首先需要到 DNS 服务器查询主机所对应的 IP 地址。
    通过域名去查询域名服务器,得到IP地址的过程叫做域名解析。在解析域名时,一般先静态域名解析,再动态解析域名。可以将一些常用的域名放入静态域名解析表中,这样可以大大提高域名解析效率。

 

二、DNS协议 

  级别最低的域名写在左边,级别最高的域名写在右边。域名服务主要是基于UDP 实现的,服务器的端口号为 53。

域名服务器

  域名需要由遍及全世界的域名服务器去解析,域名服务器实际上就是装有域名系统的主机。由高向低进行层次划分,可分为以下几大类:

根域名服务器:最高层次的域名服务器,也是最重要的域名服务器,本地域名服务器如果解析不了域名就会向根域名服务器求助。全球共有 13 个不同 IP 地址的根域名服务器,它们的名称用一个英文字母命名,从 a 一直到 m。 这些服务器由各种组织控制,并由 ICANN(互联网名称和数字地址分配公司)授权,由于每分钟都要解析的名称数量多得令人难以置信,所以实际上每个根服务器都有镜像服务器, 每个根服务器与它的镜像 服务器共享同一个 IP 地址,中国大陆地区内只有 6 组根服务器镜像(F,I(3 台),J,L)。当你对某个根服务器发出请求时,请求会被路由到该根服务器离你最近的镜像服务器。所有的根域名服务器都知道所有的顶级域名服务器的域名和地址,如果向根服务器发出对 0voice.com 的请求,则根服务器是不能在它的记录文件中找到与0voice.com 匹配的记录。但是它会找到.com 的顶级域名记录,并把负责.com 地址的顶级域名服务器的地址发回给请求。
顶级(TLD)域名服务器:负责管理在该顶级域名服务器下注册的二级域名。当根域名服务器告 诉查询者顶级域名服务器地址时,查询者紧接着就会到顶级域名服务器进行查询。比如还是查询 0voice.com,根域名服务器已经告诉了查询者 com 顶级域名服务器的地址, com 顶级域名服务器会找到 0voice.com 的域名服务器的记录,域名服务器检查其区域文件,并发现它有与 0voice.com 相关联的区域文件。在此文件的内部,有该主机的记录。此记录说明此主机所在的 IP 地址,并向请求者返回最终答案。

权限(权威)域名服务器:当递归解析器收到来自 TLD 域名服务器的响应时,该响应会将解析器定向到权威性域名服务器。权威性域名服务器通常是解析器查找 IP 地址过程中的最后一步。权威名称服务器包含特定于其服务域名的信息(例如,google.com),并且它可为递归解析器提供在DNS A记录中找到的服务器的 IP 地址,或者如果该域具有 CNAME记录(别名),它将为递归解析器提供一个别名域,这时递归解析器将必须执行全新 DNS 查找,以便从权威性域名服务器获取记录(通常为包含 IP 地址的 A 记录)。

本地域名服务器:当一个主机发出 DNS 查询请求的时候,这个查询请求首先就是发给本地域名服务器的。

域名解析过程

域名解析总体可分为两大步骤,第一个步骤是本机向本地域名服务器发出一个 DNS 请求报文,报文里携带需要查询的域名;第二个步骤是本地域名服务器向本机回应一个 DNS 响应 报文,里面包含域名对应的 IP 地址。从下面对 0voice.com 进行域名解析的报文中可明显 看出这两大步骤。注意:第二大步骤中采用的是迭代查询,其实是包含了很多小步骤的, 详情见下面的流程分析

其具体的流程可描述如下:
1. 主机 192.168.1.124 先向本地域名服务器 192.168.1.2 进行 递归查询
2. 本地域名服务器采用 迭代查询 ,向一个根域名服务器进行查询
3. 根域名服务器告诉本地域名服务器,下一次应该查询的顶级域名服务器 0voice.com
IP 地址
4. 本地域名服务器向顶级域名服务器 0voice.com 进行查询
5. 顶级域名服务器 .com 告诉本地域名服务器,下一步查询权限服务器 www.0voice.com
IP 地址
6. 本地域名服务器向权限服务器 www.0voice.com 进行查询
7. 权限服务器 www.0voice.com 告诉本地域名服务器所查询的主机的 IP 地址
8. 本地域名服务器最后把查询结果告诉 122.152.222.180

递归查询和迭代查询

 

 图2-18所示的例子利用了递归查询和迭代查询。从cse.nyu.edu到dns.nyu.edu发出的查询是递归查询,因为该查询以自己的名义请求dns.nyu.edu来获得该映射。而后继的3个查询是迭代查询,因为所有的回答都是直接返回给dns.nyu.edu。从理论上讲,任何DNS查询既可以是迭代的也能是递归的。例如,图2-19显示了一条DNS查询链,其中的所有查询都是递归的。实践中,查询通常遵循图2-18中的模式:从请求主机到本地DNS服务器的查询是递归的,其余的查询是迭代的。

协议报文格式

头部

会话标识(2字节):是DNS报文的ID标识,对于请求报文和其对应的应答报文,这个字段是相同的,通过它可以区分DNS应答报文是哪个请求的响应。 

标志(2字节):

QR1bit 查询 / 响应标志, 0 为查询, 1 为响应
opcode4bit 0 表示标准查询, 1 表示反向查询, 2 表示服务器状态请求
AA1bit 表示授权回答
TC1bit 表示可截断的
RD1bit 表示期望递归
RA1bit 表示可用递归
rcode4bit 表示返回码, 0 表示没有差错, 3 表示名字差错, 2 表示服务器错误( Server
Failure
数量字段(总共 8 字节): Questions、Answer RRs、Authority RRs、Additional RRs 各自
表示后面的四个区域的数目。Questions 表示查询问题区域节的数量,Answers 表示回答区
域的数量,Authoritative namesversers 表示授权区域的数量,Additional recoreds 表示
附加区域的数量

正文

 

查询名:长度不固定,且不使用填充字节,一般该字段表示的就是需要查询的域名(如果是反向查询,则为IP,反向查询即由IP地址反查域名),一般的格式如下图所示

 

查询类:通常为 1,表明是 Internet 数据

源记录

源记录(RR)包括回答区域,授权区域和附加区域

域名(2字节或不定长):它的格式和Queries区域的查询名字字段是一样的。有一点不同就是,当报文中域名重复出现的时候,该字段使用2个字节的偏移指针来表示。比如,在资源记录中,域名通常是查询问题部分的域名的重复,因此用2字节的指针来表示,具体格式是最前面的两个高位是11,用于识别指针。其余的14位从DNS报文的开始处计数(从0开始),指出该报文中的相应字节数。一个典型的例子,C00C(1100000000001100,12 正好是头部的长度,其正好指向 Queries 区域的查询名字字段)。

查询类型:表明资源记录的类型,如前文中查询类型表格所示

查询类:对于Internet信息,总是IN

生存时间(TTL):以秒为单位,表示的是资源记录的声明周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间,它同时也可以表明该资源记录的稳定程度,极为稳定的信息会被分配一个很大的值(比如86400,这是一天的秒数)

资源数据: 该字段是一个可变长字段,表示按照查询段的要求返回的相关资源记录的数
据。可以是 Address(表明查询报文想要的回应是一个 IP 地址)或者 CNAME(表明查询
报文想要的回应是一个规范主机名)等。

Wireshark抓取DNS报文

  从上到下分别是物理层、数据链路层、网络层、传输层、应用层

 可展开观察DNS协议的具体细节

三、实现DNS请求

1.首部header和question结构体

struct dns_header{
    unsigned short id;
    unsigned short flags;
    unsigned short questions;
    unsigned short answers;
    unsigned short authority;
    unsigned short additional;
};

struct dns_question{
    int length;
    unsigned short qtype;
    unsigned short qclass;
    char* name;//域名
};

2.初始化dns首部

//client send to dns server
int dns_create_header(dns_header* header){
    if(header==NULL) return -1;
    memset(header,0,sizeof(header));

    //random
    srandom(time(NULL));//设置种子(因为种子根据时间有关,每次random也会变,因此这是一个线程不安全的)
    header->id=random();//获得随机数

    header->flags=htons(0x0100);//转化为网络字节序
    header->questions=htons(1);//每次查询一个域名
    return 0;

}

3. 初始化question

strdup函数声明
#include <string.h>
char *strdup(const char *s); 

函数介绍:

  strdup()函数是c语言中常用的一种字符串拷贝库函数,一般和free()函数成对出现。

strdup()在内部调用了malloc()为变量分配内存,不需要使用返回的字符串时,需要用free()释放相应的内存空间,否则会造成内存泄漏。该函数的返回值是返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL值。

strtok() 函数声明

char *strtok(char *str, const char *delim)
  • str -- 要被分解成一组小字符串的字符串。
  • delim -- 包含分隔符的 C 字符串。

返回值:该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。 

char *strncpy(char *dest, const char *src, size_t n)

把 src 所指向的字符串复制到 dest,最多复制 n 个字符。当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。

  • dest -- 指向用于存储复制内容的目标数组。
  • src -- 要复制的字符串。
  • n -- 要从源中复制的字符数。

该函数返回最终复制的字符串。

//创建question
//hostname:www.baidu.com
//name:3www5baidu3com'\0'
int dns_create_question(dns_question* question,const char* hostname){
    if(question==NULL||hostname==NULL) return -1;
    memset(question,0,sizeof(question));
    question->name=(char*)malloc(strlen(hostname)+2);//因为要判断结尾'\0',然后再补充一个开头3
    if(question->name==NULL){//如果内存分配失败
        return -2;
    }
    question->length=strlen(hostname)+2;
    question->qtype=htons(1);//查询类型,(1表示:由域名获得 IPv4 地址)
    question->qclass=htons(1);//通常为 1,表明是 Internet 数据

    //hostname->name
    const char delim[2]=".";//分隔符,末尾补个'\0'
    char* qname=question->name;
    char* hostname_dup=strdup(hostname);//复制一份hostname  --->malloc(所以后续要free)
    char* token=strtok(hostname_dup,delim);
    while(token!=NULL){
        size_t len=strlen(token);//第一个循环token为www,len=3
        *qname=len;//先把长度放上去
        qname++;
        strncpy(qname,token,len+1);//复制www,这里不+1也是可以的,这样是为了把最后的'\0'也复制过来,因为最后也会被覆盖的。(如果这边不+1,最后一步,需要额外加上'\0')
        qname+=len;
        token=strtok(NULL,delim);//因为上一次,token获取还未结束,因此可以指定NULL即可。(注意:要依赖上一次的结果,因此也是线程不安全的)
    }
    free(hostname_dup);

}

4.合并header和question

//struct dns_header* header
//struct dns_question* question
//把上面两个合到request中 返回长度
int dns_build_requestion(dns_header* header,dns_question* question,char* request,int rlen){
    if(header==NULL||question==NULL||request==NULL) return -1;
    memset(request,0,rlen);

    //header-->request
    memcpy(request,header,sizeof(dns_header));//把header的数据 拷贝 到request中
    int offset=sizeof(dns_header);

    //question-->request
    memcpy(request+offset,question->name,question->length);
    offset+=question->length;
    memcpy(request+offset,&question->qtype,sizeof(question->qtype));
    offset+=sizeof(question->qtype);
    memcpy(request+offset,&question->qclass,sizeof(question->qclass));
    offset+=sizeof(question->qclass);
    return offset;
}

5.通过socket实现dns请求

int dns_client_commit(const char* domin){
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);//创建sockfd,AF_INET表示ipv4, SOCK_DGRAM为报文方式(UDP);
    if(sockfd<0){//创建失败
        return -1;
    }
    struct sockaddr_in servaddr={0};//服务器地址(sockaddr_in存储)
    servaddr.sin_family=AF_INET;//协议簇
    servaddr.sin_port=htons(DNS_SERVER_PORT);//端口
    servaddr.sin_addr.s_addr=inet_addr(DNS_SERVER_IP);//添加dns服务器ip

    int ret=connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));//目的是为sendto开辟一条路径, 
    printf("connect:%d",ret);

    dns_header header={0};
    dns_create_header(&header);
    dns_question question={0};
    dns_create_question(&question,domin);

    char request[1024]={0};//假设定义为1024长度
    int length = dns_build_requestion(&header,&question,request,1024);

    //request 发送请求
    int slen=sendto(sockfd,request,length,0,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));

    //receive from 接受数据
    char response[1024]={0};
    struct sockaddr_in addr;
    size_t addr_len=sizeof(struct sockaddr_in);
    int n = recvfrom(sockfd,response,sizeof(response),0,(struct sockaddr*)&addr,(socklen_t*)&addr_len);
    printf("recvfrom:%d \n",n);
    for(int i=0;i<n;i++){
        printf("%c",response[i]);
    }
    for(int i=0;i<n;i++){
        printf("%x",response[i]);
    }
    printf("\n");
    return n;
}

6.解析结果

    C 库函数 void *calloc(size_t nitems, size_t size) 分配所需的内存空间,并返回一个指向它的指针。malloc 和 calloc 之间的不同点是,malloc 不会设置内存为零,而 calloc 会设置分配的内存为零。

void *calloc(size_t nitems, size_t size)
  • nitems -- 要被分配的元素个数。
  • size -- 元素的大小。
 void bzero(void *s, int n);

bzero()将参数s 所指的内存区域前n 个字节全部设为零

typedef struct dns_item{
    char *domain;
    char *ip;
}dns_item;

int is_pointer(int in) {  //in与0xc0相与,结果等于0xc0时为真 192
    return ((in & 0xC0) == 0xC0);
}

//参数1:存放DNS服务器返回结果的缓冲区  参数2:指向返回结果某一区域的指针 参数3存放Answer中name字段的缓冲区
//将Answer中name字段放入缓冲区
void dns_parse_name(unsigned char *chunk, unsigned char *ptr, char *out, int *len) {
    int flag = 0, n = 0, alen = 0;
    char *pos = out + (*len);  //pos指向

    while (1) {

        flag = (int)ptr[0];
        if (flag == 0) break;

        if (is_pointer(flag)) {

            n = (int)ptr[1];
            ptr = chunk + n;
            dns_parse_name(chunk, ptr, out, len);
            break;

        } else {

            ptr ++;
            memcpy(pos, ptr, flag);
            pos += flag;
            ptr += flag;

            *len += flag;
            if ((int)ptr[0] != 0) {
                memcpy(pos, ".", 1);
                pos += 1;
                (*len) += 1;
            }
        }

    }
}

// 参数1:存放dns服务器返回结果的缓冲区  参数2:指向dns_item结构体的指针
int dns_parse_response(char *buffer, struct dns_item **domains){
    int i = 0;
    unsigned char *ptr = (unsigned char* )buffer;  //ptr是指向buffer的指针

    ptr += 4;  //向后移动4字节
    //将一个无符号短整型数从网络字节顺序转换为主机字节顺序
    int querys = ntohs(*(unsigned short*)ptr); //获取questions字段 查询问题区域节的数量

    ptr += 2;
    int answers = ntohs(*(unsigned short*)ptr);//获取Answer RRs字段

    ptr += 6;  //指向Queries字段
    for (i = 0;i < querys;i ++) { //此处循环目的是跳过查询字段
        while (1) {
            int flag = (int)ptr[0]; //第一部分的长度
            ptr += (flag + 1);  //ptr指向下一部分

            if (flag == 0) break;  //查询名的结尾为0
        }
        ptr += 4; //指向回答区域
    }

    char cname[128], aname[128], ip[20], netip[4];
    int len, type, ttl, datalen;

    int cnt = 0;
    struct dns_item *list = (struct dns_item*)calloc(answers, sizeof(struct dns_item)); //为dns_item结构体分配内存空间
    if (list == NULL) {
        return -1;
    }

    for (i = 0;i < answers;i ++) {

        bzero(aname, sizeof(aname));  //将aname空间元素置为0
        len = 0;
        //ptr指向Answers字段  将buffer中answer的Name字段放入aname中
        dns_parse_name((unsigned char* )buffer, ptr, aname, &len);
        ptr += 2;

        type = htons(*(unsigned short*)ptr);
        ptr += 4;

        ttl = htons(*(unsigned short*)ptr);
        ptr += 4;

        datalen = ntohs(*(unsigned short*)ptr);
        ptr += 2;

        if (type == DNS_CNAME) {

            bzero(cname, sizeof(cname));
            len = 0;
            dns_parse_name((unsigned char* )buffer, ptr, cname, &len);
            ptr += datalen;

        } else if (type == DNS_HOST) {

            bzero(ip, sizeof(ip));

            if (datalen == 4) {
                memcpy(netip, ptr, datalen);
                inet_ntop(AF_INET , netip , ip , sizeof(struct sockaddr));

                printf("%s has address %s\n" , aname, ip);
                printf("\tTime to live: %d minutes , %d seconds\n", ttl / 60, ttl % 60);

                list[cnt].domain = (char *)calloc(strlen(aname) + 1, 1);
                memcpy(list[cnt].domain, aname, strlen(aname));

                list[cnt].ip = (char *)calloc(strlen(ip) + 1, 1);
                memcpy(list[cnt].ip, ip, strlen(ip));

                cnt ++;
            }

            ptr += datalen;
        }
    }

    *domains = list;
    ptr += 2;

    return cnt;
}

7.main函数

int main(int argc,char* argv[]){
    if(argc<2) return -1;
    dns_client_commit(argv[1]);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

佰维存储通过注册:拟募资8亿 国家集成电路基金是二股东

雷递网 雷建平 11月23日深圳佰维存储科技股份有限公司&#xff08;简称&#xff1a;“佰维存储”&#xff09;日前通过注册&#xff0c;准备在科创板上市。佰维存储计划募资8亿元&#xff0c;3亿元用于惠州佰维先进封测及存储器制造基地建设项目&#xff0c;2亿元用于先进存储器…

基于FME Desktop和FME Server的数据增量自动更新

一、自动更新的意义 自动更新使数据保持良好的现势性&#xff0c;具有良好现势性的数据可以准确反映最新情况&#xff0c;为领导者决策分析判断提供有力保障。 一年一度的国土变更调查就是国家为了及时全面查清我国土地利用状况&#xff0c;掌握详实准确的土地基础数据现势情…

项目分享:新年可以做的副业项目,红包封面制作

新的一年即将到来。今天想推荐一个非常暴力和稳定的项目&#xff0c;红包封面。这个项目在春节期间特别强大&#xff0c;因为新年包已经成为中国人的传统&#xff0c;从原来的纸包到现在的VX包已经成为一项必不可少的活动。因此&#xff0c;从需求的角度来看&#xff0c;这个项…

Linux 搭建本地镜像源(CentOS 离线 yum)

使用 RPM 包搭建本地镜像源 1. 下载所有源中的 RPM 包 yum -y install httpd yum-utils createrepo 创建 RPM 包的下载目录 mkdir /var/www/html/centos启动 httpd 服务 [rootlocalhost ~]# systemctl start httpd [rootlocalhost ~]# ss -antulp | grep :80 tcp LISTEN …

nerdctl 工具(用于 containerd 但兼容 docker CLI 习惯)

简介 nerdctl 是用于 containerd 并且 兼容 docker cli 习惯的管理工具&#xff0c;主要适用于刚从 docker 转到 containerd 的用户&#xff0c;操作 containerd 的命令行工具 ctr 和 crictl 不怎么好用&#xff0c;所以就有了 nerdctl。 要特别说明的是&#xff1a;nerdctl …

还在每天玩单调的控制台窗口?赶紧进来!!!用EasyX画出自己的优美窗口(万字教程,一文入门)

EasyX图形库教程 本文的封面第三章照片来自博客&#xff1a;爱心气球 文章目录EasyX图形库教程前言1.EasyX是什么&#xff1f;2.EasyX的安装开始教程1.基本概念1.1颜色1.2坐标2.创建窗口 -- 基本框架3.颜色设置3.1背景颜色3.2设置线条颜色3.3设置文本颜色3.4设置填充颜色4样式…

计算机毕业设计之java+ssm家校通网站

项目介绍 随着网络技术的飞速发展&#xff0c;网络已渗透到全人类的各个方面&#xff0c;深刻影响着我们的生活和工作方式。家校通网站给教育带来了更广阔的发展空间。家校通网站有对部分类似网站进行分析&#xff0c;找到规律和方法&#xff0c;吸取其特点&#xff0c;构思自…

Win11关闭Superfetch服务的操作方法分享

Win11关闭Superfetch服务的操作方法分享。有用户发现自己电脑在开机的时候&#xff0c;都会出现Superfetch服务的相关程序进程。为了优化自己的运行内存&#xff0c;想要将这个功能给进行关闭。那么电脑的Superfetch服务怎么去关闭&#xff0c;一起来看看关闭的方法吧。 操作方…

天宇优配|北上广深角逐“国字号”数据交易所 行业爆点

今日&#xff0c;上海数据生意地点揭牌一周年之际&#xff0c;将发动数据生意节&#xff0c;并将探究树立数交所国际板。10天前&#xff0c;深圳数据生意所正式揭牌。至此&#xff0c;北上广深四个一线城市均已树立数据生意所。 数据作为新型生产要素&#xff0c;正成为各地争相…

想过为什么家里的IP是192.168开头的吗?

为什么我们家里的IP都是192.168开头的&#xff1f; 是的&#xff0c;就是我&#xff0c;先不做什么技术博主了&#xff0c;做个老情感博主&#xff08;手动狗头&#xff09;。 来讲个故事。 资深老舔狗小王今天很兴奋&#xff0c;说什么也要请大家喝奶茶。 因为他说他感觉要跟…

基于ModelCoder的汽车悬挂系统建模

悬挂系统是汽车的车架与车桥或车轮之间的一切传力连接装置的总称&#xff0c;其功能是传递作用在车轮和车架之间的力和力矩&#xff0c;并且缓冲由不平路面传给车架或车身的冲击力&#xff0c;衰减由此引起的振动&#xff0c;以保证汽车平顺行驶。 悬挂系统主要功能为支持车身…

事业编招聘:国家无线电监测中心2022年公开招聘

一、单位简介 国家无线电监测中心检测中心是国家无线电监测中心/国家无线电频谱管理中心下属的独立事业法人机构&#xff0c;主要从事无线电技术领域的检测认证、产品研发、科研标准、行业咨询和政府支撑等工作&#xff0c;在北京、河北永清、广东深圳、上海、湖南长沙、四川成…

如何在你的 wordpress 网站中添加搜索框

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网站】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且…

计算机毕业设计之java+ssm理发店会员管理系统

项目介绍 本理发店会员管理系统主要包括系统用户管理模块、商品项目模块、会员消费管理、会员信息管理、会员充值管理、登录模块、和退出模块等多个模块。本系统基于SSM(SpringSpringMVCMyBatis)框架,适用于毕业设计&#xff0c;采用javaweb,基于B/S模式,Myeclipse或者eclipse…

HDI激光钻孔和常见问题

随着电子产品不断升级&#xff0c;对pcb工艺也会越来越高。且由于结构空间原因&#xff0c;对pcb的体积也会越来越小。因此pcb的工艺会越来越复杂。 一&#xff0c;什么样的孔才会用激光设备&#xff1f; 很多工程师看到工艺能力的时候&#xff0c;上面写的最小孔0.1mm&#x…

【计算机毕业设计】35.流浪动物救助及领养管理系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;流浪动物救助及领养管理也不例外&#xff0c;但目前国内的有些宠物店仍然都使用人工管理&#xff0c;宠物店的规模越来越大&…

数据结构-期末复习重要知识点总结

目录 第一章-绪论 第二章-线性表 3.顺序表表示 4.顺序表基本运算 5.链表 6.链表的基本运算 7.循环链表 8.双链表 9.静态链表 10.一元多项式表示及相加 第三章-限定性线性表&#xff08;栈与队列&#xff09; 1.顺序栈 2.链栈 3.链队列 4.循环队列 5.习题 第四章…

JavaScript中常用对象方法总结

Object.create()创建对象 该方法用于创建一个新对象&#xff0c;新建对象具有指定原型和若干个指定属性&#xff1b; Object.create(proto) Object.create(proto, propertiesObject) 该方法接收两个参数&#xff0c;第一个参数是新建对象的指定原型对象&#xff0c;第二个参数…

校企合作共建体系:亚马逊云科技的云计算人才培养之道

1984年的一天&#xff0c;有一位老人在参观两名青少年展示计算机操作时&#xff0c;说出了一句被人们传颂至今的名言&#xff1a;“计算机的普及要从娃娃抓起。”数十年后的今天&#xff0c;伴随着云计算在全球的风起云涌&#xff0c;中国对云计算人才的需求也在与日俱增。面对…

RabbitMQ系列【15】AmqpAdmin使用详解

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言1、查询队列信息2、声明、删除交换机3、声明、删除队列4、声明、删除交换机/队列绑定关系5、初始化前言 在之前&#xff0c;我们都是通过注入Bean的方式去声明交换机、队列&#xff0c;应用…