【Linux】socket套接字

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:折纸花满衣
🏠个人专栏:题目解析

在这里插入图片描述


目录

  • 👉🏻IP地址和端口号
    • pid和port的关系
  • 👉🏻TCP和UDP
  • 👉🏻网络字节序
  • 👉🏻socket网络编程以及接口函数
    • socket概念
    • socket
    • bind
    • listen
    • accept
    • connect
    • 运用socker接口函数实现服务端和客户端的实例代码
  • 👉🏻sockaddr结构
    • struct sockaddr
    • struct sockaddr_in

👉🏻IP地址和端口号

IP地址和端口号是网络通信中重要的概念,它们用于标识网络中的设备和应用程序。这两者结合在一起,可以唯一确定网络中的一个进程,从而实现进程间的通信。

  1. IP地址(Internet Protocol Address):IP地址是网络上设备的标识符,用于在网络中唯一标识一个设备(如计算机、路由器等)。IP地址分为IPv4和IPv6两种格式。IPv4地址通常由四个用点分隔的十进制数组成(例如,192.168.1.1),而IPv6地址则更长,由八组十六进制数构成(例如,2001:0db8:85a3:0000:0000:8a2e:0370:7334)。在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址

  2. 端口号(Port Number):端口号是一个逻辑地址,用于标识一个特定的进程或服务。在通信中,每个数据包都会标记源端口和目标端口。端口号的范围是从0到65535,其中0到1023是被系统保留的一些常用端口,用于一些特定的服务(比如HTTP的端口80,HTTPS的端口443等)。端口号是一个2字节16位的整数;一个端口号只能被一个进程占用

一个进程可以绑定多个端口号; 但是一个端口号不能被多个进程绑定

IP地址和端口号结合在一起,可以唯一地标识网络中的一个进程。例如,一个Web服务器可能会使用IP地址192.168.1.1和端口号80来提供HTTP服务。当客户端想要访问这个Web服务器时,它会使用服务器的IP地址和端口号来建立连接并发送请求。服务器收到请求后,会通过端口号将请求交给相应的Web服务进程来处理,并将响应返回给客户端。

pid和port的关系

  1. PID(进程标识符)

    • PID是操作系统给每个正在运行的进程分配的唯一标识符。
    • PID在系统范围内是唯一的,它用于操作系统在管理和跟踪进程时进行标识。
    • PID通常是一个整数值,其范围取决于操作系统。在大多数Unix-like系统中,PID从1开始递增,直到达到系统所能分配的最大值。
  2. 端口号

    • 端口号是用于标识正在运行的网络服务或应用程序的数字标识符。
    • 端口号是网络通信中的概念,在进程间通信(IPC)中通常不涉及。
    • 端口号的范围是从0到65535,其中0到1023是系统保留端口,用于一些常见的网络服务,如HTTP(端口80)和HTTPS(端口443)。

虽然PID和端口号都用于标识进程或服务,但它们在不同的上下文中发挥作用。PID是操作系统级别的标识符,用于管理和跟踪进程,而端口号是网络通信中用于标识正在运行的网络服务或应用程序的标识符

总的来说就是port的主要作用就是将操作系统中的进程管理与网络解耦,port用来专门进行网络通信的,在网络中进行进程标识,虽然二者都是标识进程的id,但是作用域不同,所以也不冲突。

👉🏻TCP和UDP

  1. TCP(Transmission Control Protocol)传输控制协议

    • TCP 是一种面向连接的、可靠的基于字节流的传输协议。
    • TCP 提供了可靠的数据传输,通过确认机制重传机制流量控制来确保数据的可靠性和顺序性。
    • TCP 在通信开始前需要建立连接(三次握手),然后在通信结束后进行连接的断开(四次挥手)。
    • TCP 适用于需要可靠数据传输和顺序传输的应用场景,如网页浏览、文件传输等。
  2. UDP(User Datagram Protocol)用户数据报协议

    • UDP 是一种简单的无连接的不可靠的传输协议。
    • UDP 不提供数据传输的可靠性和顺序性,数据包可能会丢失、重复或乱序到达
    • UDP 的优点是速度快开销小,适用于一些实时性要求高、数据丢失可容忍的应用场景。
    • UDP 不需要建立连接,通信双方直接发送数据包,因此在通信开始和结束时没有连接建立和断开的过程。

总的来说,TCP 提供了可靠的数据传输服务,适用于需要数据完整性和顺序性的场景;而 UDP 则提供了更快的传输速度,适用于一些实时性要求高、对数据丢失不敏感的场景,如音视频传输、在线游戏等。选择使用哪种协议取决于应用的需求和对数据传输特性的要求。

👉🏻网络字节序

在C语言的学习的时候,我们学习过了大小端的知识,大端就是将数据的高位字节存储在内存地址中的低位地址,小端则反之。
由于每个机器采用的大小端都不一样,所以容易导致数据传输的字节顺序会出问题。
所以网络规定:所有到达网络的数据,必须是大端,所有从网络收到数据的机器,都会知道数据是大端(之所以采取大端,是因为可读性比较高)

网络字节序是一种规范,用于在网络上跨越不同体系结构的计算机之间进行数据通信时统一数据的字节顺序。它定义了在网络传输中使用的标准字节顺序,以确保数据在发送和接收端正确解释。

在网络字节序中,数据被以大端序(Big-Endian)的方式传输,即最高有效字节在前,最低有效字节在后。这与许多计算机体系结构的本地字节序(如x86架构的小端序)可能不同。

网络字节序通常用于以下方面:

  1. 网络通信协议:许多网络通信协议(如TCP/IP、UDP、HTTP)都要求在网络上传输数据时使用网络字节序,以确保数据在不同计算机上的解释一致。

  2. 网络编程:在进行网络编程时,开发人员通常需要手动将数据从本地字节序转换为网络字节序,以便正确发送到网络上。类似地,在接收数据时,也需要将数据从网络字节序转换为本地字节序。

  3. 数据存储:有时候,数据需要以网络字节序的形式存储到文件或数据库中,以便后续在网络上传输或从网络接收时能够正确解释。


为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络
字节序和主机字节序的转换。
🌨这些函数通常用于在网络编程中进行字节序的转换,以确保在不同计算机之间正确地传输数据。这些函数包括:

  1. htonl(host to network long):

    • 函数原型uint32_t htonl(uint32_t hostlong)
    • 作用:将32位无符号整数从主机字节序转换为网络字节序(大端序)。
    • 参数意义hostlong是要转换的32位整数。
    • 返回值:返回转换后的网络字节序的32位无符号整数。
  2. htons(host to network short):

    • 函数原型uint16_t htons(uint16_t hostshort)
    • 作用:将16位无符号短整数从主机字节序转换为网络字节序(大端序)。
    • 参数意义hostshort是要转换的16位短整数。
    • 返回值:返回转换后的网络字节序的16位无符号短整数。
  3. ntohl(network to host long):

    • 函数原型uint32_t ntohl(uint32_t netlong)
    • 作用:将32位无符号整数从网络字节序(大端序)转换为主机字节序。
    • 参数意义netlong是要转换的32位整数。
    • 返回值:返回转换后的主机字节序的32位无符号整数。
  4. ntohs(network to host short):

    • 函数原型uint16_t ntohs(uint16_t netshort)
    • 作用:将16位无符号短整数从网络字节序(大端序)转换为主机字节序。
    • 参数意义netshort是要转换的16位短整数。
    • 返回值:返回转换后的主机字节序的16位无符号短整数。
  • 这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回 ;
  • 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

这些函数通常用于网络编程中,以便在发送和接收数据时正确地处理字节序,确保数据在不同主机之间的传输和解释一致。在大多数情况下,主机字节序是指本地计算机的字节序,而网络字节序是指大端序

👉🏻socket网络编程以及接口函数

socket概念

Socket(套接字)是在网络编程中用于实现网络通信的一种机制。它提供了一种在不同主机之间进行双向通信的方式,使得客户端和服务器之间可以进行数据交换。

具体来说,Socket是一种通信端点,可以用于在两个计算机之间建立连接并进行数据传输。它可以看作是一种抽象接口,用于通过网络在进程之间传递数据。在网络编程中,Socket通常通过套接字地址(包括IP地址和端口号)来标识。套接字地址用于唯一地标识网络上的每个通信端点。

🌈Socket通常分为两种类型:

  1. 流套接字(Stream Socket):也称为TCP套接字,提供面向连接的、可靠的、双向的字节流通信。在使用流套接字时,通信双方必须先建立连接,然后才能进行数据传输。TCP协议就是基于流套接字实现的。

  2. 数据报套接字(Datagram Socket):也称为UDP套接字,提供无连接的、不可靠的数据报通信。在使用数据报套接字时,通信双方无需建立连接,每个数据报都是独立的,可能会丢失或重复。UDP协议就是基于数据报套接字实现的。

🌈Socket编程通常涉及以下步骤:

  • 创建Socket:在编程中创建一个套接字对象,以便于后续的通信。
  • 绑定地址:将套接字绑定到一个特定的地址和端口上,以便其他计算机可以找到并与之通信。
  • 监听连接(仅针对服务器端):对于服务器端程序,需要开始监听传入的连接请求。
  • 建立连接(仅针对客户端):对于客户端程序,需要与服务器端建立连接。
  • 数据传输:通过套接字进行数据的发送和接收。
  • 关闭连接:通信完成后,关闭套接字以释放资源。

socket

Socket函数是用于创建套接字的系统调用,在网络编程中非常重要。具体来说,Socket函数用于创建一个套接字对象,以便后续的通信。

以下是Socket函数的一般信息:

  • 函数原型

    int socket(int domain, int type, int protocol);
    
  • 作用:创建一个套接字对象,用于后续的网络通信。

  • 参数意义

    • domain:指定套接字的协议族,常用的有以下几种:

      • AF_INET:IPv4协议族
      • AF_INET6:IPv6协议族
      • AF_UNIX:Unix域协议族
      • 等等,还有其他协议族
    • type:指定套接字的类型,常用的有以下几种:

      • SOCK_STREAM:流套接字,提供面向连接的、可靠的、双向的字节流通信(如TCP套接字)。
      • SOCK_DGRAM:数据报套接字,提供无连接的、不可靠的数据报通信(如UDP套接字)。
      • SOCK_RAW:原始套接字,用于直接访问网络层,通常需要特权。
      • 等等,还有其他类型的套接字
    • protocol:指定套接字所使用的协议,通常为0表示由系统根据domaintype参数自动选择合适的协议。例如,在IPv4下,TCP协议的值为IPPROTO_TCP,UDP协议的值为IPPROTO_UDP

  • 返回值:若成功创建套接字,则返回一个新的套接字描述符(非负整数),用于后续的操作;若失败,则返回-1,并设置全局变量errno表示错误类型。

在使用Socket函数创建套接字后,通常需要根据具体的网络通信需求,调用其他函数来设置套接字选项、绑定地址、建立连接等操作,从而实现完整的网络通信功能。

bind

bind函数用于将套接字与特定的地址(IP地址和端口号)绑定在一起,以便其他计算机可以找到并与之通信。具体来说,bind函数在服务器端程序中通常用于指定服务器的监听地址和端口。

以下是bind函数的一般信息:

  • 函数原型

    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
  • 作用将套接字与特定的地址(IP地址和端口号)绑定在一起,以便进行通信

  • 参数意义

    • sockfd:表示要绑定的套接字描述符,即通过socket函数创建的套接字对象。

    • addr:指向存储地址信息的结构体的指针,通常是sockaddr结构体或其派生结构体(如sockaddr_in结构体),用于指定要绑定的地址信息

    • addrlen:表示存储在addr指针中的地址结构体的长度。

  • 返回值:若成功绑定地址,则返回0;若失败,则返回-1,并设置全局变量errno表示错误类型。

在调用bind函数之前,通常需要先创建套接字对象,并设置好地址信息。成功绑定地址后,服务器端就可以通过监听该地址来接受客户端的连接请求,从而建立通信连接。需要注意的是,同一时间内,一个端口只能被一个套接字绑定,否则会导致绑定失败。

listen

listen函数用于将一个套接字设置为被动监听状态,使其能够接受连接请求。通常在服务器端程序中,调用listen函数来准备接受客户端的连接请求

以下是listen函数的一般信息:

  • 函数原型

    int listen(int sockfd, int backlog);
    
  • 作用:将一个套接字设置为被动监听状态,以便接受连接请求。

  • 参数意义

    • sockfd:表示要设置监听状态的套接字描述符,即通过socket函数创建的套接字对象。

    • backlog:表示在内核中允许的连接请求的最大排队数量。当有新的连接请求到达时,如果等待队列已满,则后续的连接请求将被拒绝。注意,该参数不同操作系统的取值范围可能有所不同。

  • 返回值:若成功设置监听状态,则返回0;若失败,则返回-1,并设置全局变量errno表示错误类型。

调用listen函数之后,套接字将进入被动监听状态,开始等待客户端的连接请求。一旦有新的连接请求到达,并且内核等待队列未满,那么服务器端就可以通过accept函数接受这些连接请求,并建立通信连接。需要注意的是,调用listen函数并不会阻塞程序的执行,而是将套接字设置为监听状态后立即返回。

accept

accept函数用于接受客户端的连接请求,并创建一个新的套接字与客户端进行通信。通常在服务器端程序中,调用accept函数来处理客户端的连接请求,并建立通信连接。

以下是accept函数的一般信息:

  • 函数原型

    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
  • 作用:接受客户端的连接请求,并创建一个新的套接字与客户端进行通信

  • 参数意义

    • sockfd表示已经处于监听状态的套接字描述符,即通过socket函数创建的套接字对象。

    • addr:用于存储客户端地址信息的结构体指针。当成功接受客户端连接后,该指针所指向的结构体将被填充为客户端的地址信息。

    • addrlen:表示存储在addr指针中的地址结构体的长度。在调用accept函数之前,需要将其设置为可修改的地址结构体的长度。

  • 返回值:若成功接受连接请求,则返回一个新的套接字描述符,用于与客户端进行通信;若失败,则返回-1,并设置全局变量errno表示错误类型。

调用accept函数之后,服务器端程序将会阻塞,直到有新的客户端连接请求到达。一旦有客户端连接成功,accept函数将返回一个新的套接字描述符,服务器可以使用这个新的套接字与客户端进行通信。同时,accept函数还会将客户端的地址信息存储在提供的addr结构体中,方便服务器端获取客户端的地址和端口信息。

connect

connect函数用于建立与远程服务器的连接。通常在客户端程序中,调用connect函数来连接服务器,以便进行数据通信。

以下是connect函数的一般信息:

  • 函数原型

    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
  • 作用:建立与远程服务器的连接。

  • 参数意义

    • sockfd:表示客户端本地套接字的描述符,即通过socket函数创建的套接字对象。

    • addr:指向远程服务器地址信息的结构体指针,通常是通过调用getaddrinfo或手动构建的。

    • addrlen:表示提供给addr参数的地址结构体的长度。

  • 返回值:若连接成功,则返回0;若失败,则返回-1,并设置全局变量errno表示错误类型。

调用connect函数后,客户端会尝试与指定的服务器建立连接。如果连接成功,那么客户端就可以通过已连接的套接字进行数据通信。如果连接失败,则通常是由于服务器不可达、端口未开放或网络问题等原因。在连接函数返回之前,通常会阻塞程序的执行,直到连接建立成功或失败。

运用socker接口函数实现服务端和客户端的实例代码

服务器端代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define PORT 8080
#define BACKLOG 5
#define BUFFER_SIZE 1024

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE] = {0};
    const char *hello = "Hello from server";

    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 设置套接字选项,允许地址重用
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 将套接字绑定到指定的端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 开始监听连接请求
    if (listen(server_fd, BACKLOG) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    // 等待并接受客户端连接
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    // 从客户端接收数据
    read(new_socket, buffer, BUFFER_SIZE);
    printf("Client: %s\n", buffer);

    // 向客户端发送数据
    send(new_socket, hello, strlen(hello), 0);
    printf("Hello message sent\n");

    return 0;
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char buffer[BUFFER_SIZE] = {0};
    const char *hello = "Hello from client";

    // 创建套接字
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\n Socket creation error \n");
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // 将IPv4地址从文本转换为二进制形式
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    // 连接到服务器
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("\nConnection Failed \n");
        return -1;
    }

    // 向服务器发送数据
    send(sock, hello, strlen(hello), 0);
    printf("Hello message sent\n");

    // 从服务器接收数据
    read(sock, buffer, BUFFER_SIZE);
    printf("Server: %s\n",buffer);

    return 0;
}

这个例子中,服务器端创建了一个套接字,绑定到指定的端口,并监听连接请求。当客户端连接到服务器时,服务器接受连接并接收来自客户端的消息,然后向客户端发送一条消息。客户端连接到服务器,向服务器发送一条消息,并接收来自服务器的响应。

👉🏻sockaddr结构

struct sockaddr

struct sockaddr 是一个通用的套接字地址结构体,用于表示套接字的地址信息。在网络编程中,它通常被用于指定套接字的地址,包括 IP 地址和端口号。这个结构体是用于支持不同协议族的通用性。

下面是 struct sockaddr 的定义:

struct sockaddr {
    unsigned short sa_family;   // 地址族(Address Family),如 AF_INET(IPv4)或 AF_INET6(IPv6)
    char sa_data[14];           // 地址数据,包含具体的地址信息
};

由于 struct sockaddr 是一个通用的结构体,它的大小固定为 16 字节。因此,对于具体的地址族(如 IPv4 或 IPv6),通常会使用它的变体,如 struct sockaddr_in(IPv4)或 struct sockaddr_in6(IPv6),它们在 struct sockaddr 的基础上添加了一些额外的字段来表示特定地址族的地址信息。

在实际使用中,通常不直接使用 struct sockaddr,而是使用具体的地址结构体,如 struct sockaddr_instruct sockaddr_in6,因为它们提供了更多的字段来存储地址信息,并且更方便使用。

struct sockaddr_in

struct sockaddr_in 是用于表示 IPv4 地址的套接字地址结构体,在网络编程中经常使用。它包含在 <netinet/in.h> 头文件中。

下面是 struct sockaddr_in 的定义:

struct sockaddr_in {
    short int sin_family;           // 地址族(Address Family),通常为 AF_INET
    unsigned short int sin_port;    // 16 位端口号,网络字节序(big-endian)
    struct in_addr sin_addr;        // IPv4 地址结构体
    unsigned char sin_zero[8];      // 用于填充,使 sockaddr_in 和 sockaddr 的大小相同
};

其中:

  • sin_family:表示地址族,通常设置为 AF_INET,表示 IPv4 地址族。
  • sin_port:表示端口号,是一个 16 位的整数,以网络字节序(big-endian)存储。
  • sin_addr:是一个 struct in_addr 结构体,用于存储 IPv4 地址信息
  • sin_zero:用于填充,使 struct sockaddr_instruct sockaddr 的大小相同,总共占据 8 个字节。

struct in_addr 的定义如下:

struct in_addr {
    uint32_t s_addr;    // IPv4 地址,32 位无符号整数,以网络字节序存储
};

struct sockaddr_in 通常用于存储和表示 IPv4 地址信息,例如在创建套接字、绑定地址和连接远程主机时使用。使用这个结构体可以方便地操作和管理 IPv4 地址


如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长

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

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

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

相关文章

数据分析之Tebleau 的度量名称和度量值

度量名称 包含所有的维度 度量值 包含所有的度量 度量名称包含上面所有的维度&#xff0c;度量值包含上面所有的度量 当同时创建两个或两个以上度量或维度时&#xff0c;会自动创建度量名称和度量值 拖入省份为行(这会是还没有值的) 可以直接将销售金额拖到数值这里 或者将销售…

C++11 shared_from_this学习

最近学习网络变成发现一些C源码库中封装对象时会公有继承enable_shared_from_this&#xff1b; 用一个案例进行说明&#xff0c;案例代码如下&#xff1a; #include <iostream> #include <memory> #include <stdio.h>using namespace std;class C : public…

ComfyUI一直提示transformers需要升级,怎么解决?

&#x1f3a1;背景 最近通过秋叶的启动器使用Comfyui的时候&#xff0c;总是会有个弹窗提示transformers需要升级&#xff0c;你会发现&#xff0c;就算是更新了ComfyUI版本&#xff0c;升级了所有插件&#xff0c;升级了transformers库&#xff0c;这个提示仍然存在&#xff…

【Spring Security】 快速入门

文章目录 一、 身份认证Demo1、创建工程2、代码编写2.1、Controller2.2、Html2.3、application.properties配置 3、启动项目并访问 二、Spring Security 默认做了什么二、底层原理1.概述2.FiltersDelegatingFilterProxyFilterChainProxySecurityFilterChainSecurity Filters 三…

【docker】搭建Nexus私服

1、拉取镜像 docker pull sonatype/nexus3 2、运行镜像 docker run -d -p 10002:8081 -e NEXUS_CONTEXTnexus --name nexus-quick sonatype/nexus3 3、访问地址&#xff1a; http://localhost:10002/nexus &#xff01;&#xff01;&#xff01;注意我的端口号是…

数据结构--循环链表(C语言实现)

一.循环链表的设计 typedef struct CNode{ int data; struct CNode* next; }CNode ,*CList; 2.循环链表的示意图: 3.循环链表和单链表的区别: 唯一区别,没有空指针,尾节点的后继为头,为循环之意. 二.循环链表的实现 //初始化return true; }//返回key的前驱地址&#xff0c;如果…

查找--二分查找(Binary Search)

二分查找属于静态查找表&#xff0c;当以有序表表示静态查找表时&#xff0c;查找函数可用折半查找来实现。 查找过程&#xff1a;先确定待查记录所在的范围&#xff08;区间&#xff09;&#xff0c;然后逐步缩小范围直到找到或找不到该记录为止。 以处于区间中间位置记录的…

【Chiplet】技术总结

Chiplet基本知识点汇总 1. Wafer, die, chip, cell的区分2. MCM, SiP, SoC, Chiplet的区别4. Chiplets的先进封装5. Chiplet发展阶段 Chiplet基本知识点汇总 1. Wafer, die, chip, cell的区分 Wafer: 晶圆&#xff0c;指一整个晶圆硅片。 Die: 从晶圆上切分下来的小方格&a…

本地GPU调用失败问题解决3重新配置anaconda环境(成功)

1、右键“以管理员身份”打开anaconda prompt conda create -n python 3.9 2、使用官方下载源的配置 3、修改conda下载超时 conda config --set remote_connect_timeout_secs 60 conda config --set remote_read_timeout_secs 100 查看配置结果conda config --show 配置内…

HarmonyOS实战开发-slider组件的使用

介绍 本篇Codelab主要介绍slider滑动条组件的使用。如图所示拖动对应滑动条调节风车的旋转速度以及缩放比例。 相关概念 slider组件&#xff1a;滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调节、亮度调节等应用场景。 环境搭建 软件要求 DevEco Stu…

xftp突然无法连接虚拟机

问题描述 使用xftp连接虚拟机的时候一直显示 连接xxx.xxx.xx.xx失败 问题原因查找 首先打开本地cmd命令提示符 ping 你的虚拟机ip地址 我的是 ping 192.168.xx.xx 显示请求超时 解决方案&#xff1a; 点击打开更改适配器选项 右键vmnet 8——属性 如图前四个选项必选 单…

Linux:ip协议

文章目录 ip协议基本认识ip协议的报头 ip协议基本认识 前面对于TCP的内容已经基本结束了&#xff0c;那么这也就意味着在传输层也已经结束了&#xff0c;那么下一步要进入的是的是网络层&#xff0c;网络层中也有很多种协议&#xff0c;这里主要进行解析的是ip协议 前面的TCP…

【ensp实验】GRE和MGRE相关实验

要求&#xff1a; 1、R5为ISP,只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址; 2、R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方 R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方; R3与R5之间使用HDLC封装; 3、R1、R2、R3构建一个MGRE环境&#…

线上系统时间慢八个小时的排查之路

最近有一个新项目上线&#xff0c;在上线时&#xff0c;突然发现时间与正常时间对不上&#xff0c;少了八个小时&#xff1b;但我丝毫不慌&#xff0c;这不就是个时区的问题吗&#xff0c;简单&#xff0c;但是这一次它给我深深的上了一课&#xff0c;一起来看整个排查过程吧。…

K8S之Configmap的介绍和使用

Configmap Configmap概述Configmap的简介Configmap能解决的问题Configmap应用场景局限性 Configmap创建方法通过命令行直接创建通过文件创建指定目录创建编写Configmap资源清单Yaml文件 Configmap的使用案例通过环境变量引入&#xff1a;使用configMapKeyRef通过环境变量引入&a…

工厂方法模式与抽象工厂模式的深度对比

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自&#xff1a;设计模式深度解析&#xff1a;工厂方法模式与抽象工厂模式的深…

张颂文|永远保持好奇心的人,是永远进步的人。

哈喽,你好啊,我是雷工! 今天看到了张颂文的一段演讲,提到了他因为好奇心而被改变的人生。 如果想把单一和枯燥的工作做的更好,张颂文的办法是像一个孩子一样保持好奇心,不停地提出一些有趣的问题。 在5年的导游经历中,对每次游览的地点都像初次游览般保持好奇心,正因为…

【C语言】【Leetcode】2437. 有效时间的数目

文章目录 题目思路一、枚举思路二、回溯 题目 链接: link 思路一、枚举 这题的可以简单的看成 h1 h2 : m1 m2 的情况&#xff0c;其中 h1 和 h2 有关&#xff0c; m1 和 m2 有关&#xff0c;数目不多可以直接暴力枚举解决 int countTime(char * time) {int countHour 0;i…

【JavaWeb】Day24.Web入门——SPringBootWeb入门

什么是SPring&#xff1f; 我们可以打开Spring的官网(Spring | Home)&#xff0c;去看一下Spring的简介&#xff1a;Spring makes Java simple。Spring的官方提供很多开源的项目&#xff0c;我们可以点击上面的projects&#xff0c;看到spring家族旗下的项目&#xff0c;按照流…

PLC的大脑和心脏——CPU及西门子S7-1200CPU分类、CPU型号及端子接线图示例

CPU不断地采集输入信号&#xff0c;执行用户程序&#xff0c;刷新系统的输出。 根据供电方式和输入/输出方式的不同&#xff0c;西门子S7-1200 CPU分为3类&#xff0c;如下图1。 图1 CPU的分类 第1对字母&#xff0c;表示CPU的供电方式&#xff0c;AC&#xff08;Alternating…