linux网络编程-原理到应用-附源码(全)

news2024/11/15 1:54:06

目录

一、计算机网络分层模型

1.1 概念

1.2 OSI 七层模型

1.3 五层模型

1.4 TCP/IP四层模型

二、传输层-TCP协议

2.1 什么是TCP协议?

2.2 TCP的连接的建立和释放

2.3 基于TCP协议-只接受一个连接的范例程序

一、计算机网络分层模型

1.1 概念

计算机网络分层模型是网络通信的基础框架,它将复杂的网络通信过程划分为若干层次,每一层都执行特定的功能,并为上一层提供服务。这种分层的目的是简化网络设计,确保不同网络技术之间的兼容性和互操作性。与分层模型相关的概念包括分层、实体、协议、接口和服务。

1)分层(Layer)

分层是将网络通信过程划分为多个层次的过程。每一层关注网络通信的一个特定方面,比如物理传输、数据链路、网络路由、传输可靠性等。最著名的分层模型是OSI(开放系统互连)模型,它包含七层,以及TCP/IP模型,通常被认为包含四层。前者是学术和法律上的国际标准,后者是事实上的国际标准,即现实生活中被广泛遵循的分层模型。

2)实体(Entity)

在分层模型中,每一层都有实体,这些实体指的是执行特定层次功能的硬件或软件组件。同一层内的实体可以在不同的机器上,通过遵循相同层的协议进行通信。例如,两台计算机上的传输层实体可以是负责建立端到端连接的软件。同一层次的实体为对等实体。

3)协议(Protocol)

协议是一套规则和标准,用于控制同一层次内的实体如何相互通信。协议定义了通信的格式、时序、错误处理等。例如,TCP(传输控制协议)定义了如何在网络中的两个点之间可靠地传输数据。

4)接口(Interface)

接口是网络分层模型中,定义相邻两层之间如何交互的规范。它规定了一层如何向另一层提出服务请求,以及这些请求怎样被另一层接收和响应。接口包含了一系列的规则、命令、数据格式和过程,确保不同网络层之间的有效通信和数据交换。

服务访问点(Service Access Point,SAP)是接口概念的一个组成部分,具体化了接口在实现层次服务中的作用。

接口定义了相邻层之间交互的规范和方式,而SAP则是这种交互发生的具体逻辑位置。换句话说,SAP为接口提供了一个具体的实施机制,使得上层能够访问下层提供的服务。

5)服务(Service)

服务是指下层为紧邻上层提供的功能调用,是垂直方向的。描述了上层可以利用的具体功能和操作,但不涉及这些功能是如何实现的。服务强调的是功能性的提供,而不是实现细节。服务描述了“做什么”(功能),而不是“如何做”(实现细节)。服务是抽象的,隐藏了下层如何完成这些任务的具体细节,使得上层可以不依赖于下层的具体实现来进行设计和开发。

上层是通过SAP访问下层服务的。

1.2 OSI 七层模型

OSI(Open Systems Interconnection,开放系统互联)模型是由国际标准化组织(ISO)在1984年提出的一个网络架构模型,它将网络通信分为七个层次,每层都定义了特定的网络功能。自下而上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

1)物理层(Physical Layer)

负责传输原始比特流。它涉及的是物理设备及介质,如电缆类型、电信号传输和接收等。

2)​​​数据链路层(Data Link Layer)

确保物理链路上的无误传输。它提供了如帧同步、流量控制和错误检测等功能。

3)​​​网络层(Network Layer)

负责数据包从源到目的地的传输和路由选择。它定义了地址和路由的概念,如IP协议。

4)​​​传输层(Transport Layer)

提供端到端的数据传输服务,保证数据的完整性。它定义了如TCP和UDP协议。

5)​​​会话层(Session Layer)

管理会话,控制建立、维护和终止会话。

6)​​​​​​​​​​表示层(Presentation Layer)

处理数据的表示、编码和解码,如加密和解密。

7)​​​​​​​应用层(Application Layer)

提供网络服务给终端用户的应用程序,如HTTP、FTP、SMTP等协议。

1.3 五层模型

五层模型是将OSI模型的应用层、表示层和会话层合并为应用层,其它层不变。是为了教学而设计的一种网络分层模型。

1.4 TCP/IP四层模型

TCP/IP四层模型,亦称互联网协议套件(Internet Protocol Suite),是一种按照功能标准组织互联网及类似计算机网络中使用的一系列通信协议的框架。该套件中的基础协议包括传输控制协议(TCP)、用户数据报协议(UDP)和互联网协议(IP)。

TCP/IP协议栈(Protocol Stack)是指TCP/IP协议套件的软件实现。

1.应用层(Application Layer)

这层是用户最直接交互的部分,是软件应用通过网络进行通信的地方。应用层使用下层提供的服务来创建用户数据,将这些数据传输给同一台机器上或远程机器上的其他应用。

该层包括了SMTP、FTP、SSH、HTTP等协议,这些协议都在应用层上实现,以实现客户端与服务器之间的通信和数据交换。

2.传输层(Transport Layer)

传输层管理着端到端的通信,即主机到主机的通信。它的主要职责是为不同主机上的应用程序提供数据传输,同时保证这些数据的完整性和可靠性。

在传输层,主要的协议有TCP(Transmission Control Protocol),它提供顺序的、可靠的、双向的连接流,并管理报文段的发送,确保无错误、不丢失、不重复、按序到达;以及UDP(User Datagram Protocol),它提供一种无连接的服务,数据以数据报的形式发送,不保证顺序或响应。

3.互联网层(Internet Layer)

互联网层处理跨网络界限的数据包交换,负责将数据报文段从源地址路由到目的地址。这层抽象了实际的物理网络拓扑结构,并且定义了如何在各种网络结构中发送和接收数据包。

网络层的IP协议是构成Internet的基础。Internet上的主机都是通过IP地址来互相识别。IP协议不保证传输数据的可靠性,可能出现丢包等情况。

主要协议是IP(Internet Protocol),它定义了数据包的路由方式和网络地址。其他重要的协议包括ICMP(Internet Control Message Protocol),用于错误报告和网络诊断。

链路层(Link Layer)

链路层涉及到在物理网络上的数据通信。链路层确保网络层传来的IP数据报可以在网络的物理链接上进行传输,不管是通过有线还是无线媒介。它还负责处理与物理网络链接相关的问题,例如MAC(Media Access Control)地址寻址、帧同步、错误检测和校正。

它包括了在物理网络链接中使用的所有协议,如以太网(Ethernet)、Wi-Fi以及PPP(Point-to-Point Protocol)。

二、传输层-TCP协议

2.1 什么是TCP协议?

TCP(传输控制协议,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,广泛应用于互联网中。它旨在提供可靠的端到端通信,在发送数据之前,需要在两个通信端点之间建立连接。TCP通过一系列机制确保数据的可靠传输,这些机制包括序列号、确认应答、重传控制、流量控制和拥塞控制。

我这边重点围绕TCP报文段格式去叙述。

1)源端口号(Source Port)和目标端口号(Destination Port): 每个字段都是16位,用于标识发送和接收数据的应用层服务。端口号允许操作系统区分不同的网络服务。

2)序列号(sequence number field) 一个32位的数,用于标识从TCP源到目标的数据字节流,它用于确保数据的有序传输和重组。 TCP把数据看成一个无结构的、有序的字节流。TCP的序号是建立在传送的字节流之上,而不是建立在传送的报文段的序列之上。一个报文段的序号是该报文段首字节的字节流编号。举例来说,假设主机A上的一个进程想通过一条TCP连接向主机B上的一个进程发送一个数据流。主机A中的TCP将隐式地对数据流中的每一个字节编号。假定数据流是一个包含1000字节的序列,每次传输的报文段长度为100个字节,数据流的首字节编号是0。将为该数据流构建10个报文段。给第一个报文段分配序号0,第二个报文段分配序号100,第三个报文段分配序号200,以此类推。每一个序号被写入相应TCP报文段首部的序列号字段中。

3)确认号(acknowledgement number field) 也是一个32位的数,如果设置了ACK标志,报文段的确认号是发送方期望从对方收到的下一字节的序号。它是对之前接收到的数据的确认。假设主机A上的一个进程通过一条TCP连接和主机B上的一个进程通信,主机A已经收到了来自主机B的序号为0~122的所有字节,同时假设主机A接下来将要发送一个报文段给主机B,主机A等待主机B的数据流中序号为123及之后的所有字节,因此主机A将要发送给主机B的报文段中确认号应为123。 4)数据偏移(Data Offset) 一个4位字段,表示TCP头部的长度(以32位字为单位)。TCP头部可能包含可变数量的选项,因此长度是不确定的,需要这个字段记录长度信息。

5)保留(Reserved) 这是一个预留的6位字段,当前必须设置为0。

6)控制位(Control Bits) 标志字段共有六个比特,每个比特对应一个标志:URG、ACK、PSH、RST、SYN、FIN。这些标志用于控制TCP的不同行为,例如建立连接(SYN),终止连接(FIN),指示数据急迫性(URG)等。

URG:紧急标志,为1表示当前报文段存在被发送端上层实体置为“紧急”的数据。接收方应当优先处理这些数据。紧急指针字段指出了这部分数据的结束位置。

ACK:确认标志,为1指示确认字段的值是有效的。该报文段包含对已被成功接收报文段的确认。连接建立后,直至释放前传输的所有报文段ACK标志均为1。

PSH:为1指示接收方应立即将数据交给上层。

RST:为1表示链接出现错误,要求接收方终止连接,并重新建立连接。

SYN:该标志位用于建立连接。TCP连接建立时的前两次握手SYN为1。

FIN:为1表示发送方已经没有数据发送,想要断开连接。

7)窗口大小(Window Size) 一个16位的数值,用于控制对方发送的数据量,以避免接收方缓冲区溢出。窗口大小是流量控制的一部分,可以动态调整。

8)校验和(Checksum) 一个16位的字段,用于检查整个TCP报文段的错误。校验和确保数据在传输过程中的完整性。

9)紧急指针(Urgent Pointer) 一个16位的字段,如果URG标志被设置则为正数,表明从当前序列号开始的紧急数据的字节偏移量。

10)选项(Options) TCP头部可能包含各种可选字段,这些字段不是固定的,可能包括如最大报文段大小(MSS)、窗口缩放选项、选择性确认(SACK)等,用于优化TCP连接的性能。

11)填充(Padding) TCP是在32位体系结构上设计的,为了内存对齐以提升处理效率,需要确保它的头部长度为32位的整数倍。选项长度可变,填充的目的是确保TCP头部的长度按照32位字对齐,填充位于TCP头部的末尾。 注意:TCP数据部分不要求按照32位字对齐。

2.2 TCP的连接的建立和释放

1)TCP连接建立过程 TCP的连接建立过程又称为三次握手。 我们用小写的seq表示TCP报文头部的序号,用小写的ack表示确认号。未提到的标志位均为0。

(1)TCP服务器准备好接受连接,进入LISTEN状态,这一过程称为被动打开。

(2)第一次握手:客户端发送SYN标志为1(表示这是一个同步报文段),且seq随机的报文段,请求建立连接。此时的seq记为ISN(c)(Initial Sequence Number,初始序列号),括号中的c表示这是和客户端的序列号。客户端发送后变为SYN-SENT状态。

(3)第二次握手:服务端收到客户端的第一次握手信号,变为SYN-RCVD状态。随即确认客户端的SYN报文段,发送一个ACK和SYN标志均为1的报文段。该报文段中ack=ISN(c)+1,seq随机,标记为ISN(s),此处的s表示这是服务端的序列号。服务端变为SYN-RCVD状态。

(4)第三次握手:客户端收到服务端的第二次握手信号,变为ESTABLISHED状态,随即确认服务端的报文段,发送ACK标志为1的报文段。该报文段中ack=ISN(s)+1,seq=ISN(c)+1。服务端收到客户端的第三次握手信号之后变为ESTABLISHED状态。 下面的PPT中,大写字母组合表示相应标志位为1。

2)TCP连接释放过程 TCP的连接释放过程又称为四次挥手。 四次挥手可以由客户端发起,也可以由服务端发起。此处假设连接请求的断开操作由客户端发起。连接断开前,双方都处于ESTABLISHED状态。需要注意的是,连接建立后,即客户端和服务端处于ESTABLISHED时,双方发送的报文段ACK标志均为1。 我们用小写的seq表示TCP报文头部的序号,用小写的ack表示确认号。未提到的标志位均为0。

(1)第一次挥手:客户端发送FIN标志为1(即FINISH,表示通信结束)的报文段,请求断开连接,执行主动关闭(active close)。此时,报文段中包含对于服务端数据的确认,ACK为 1,假设ack=V。连接断开前已经历了一系列的数据传输,seq取决于之前已发送的报文段,假设seq=U。客户端状态变为FIN-WAIT-1。

(2)第二次挥手:服务端接收到第一次挥手信息,切换为CLOSE-WAIT状态,随即发送ACK标志为1,ack=U+1的报文段,此时seq=V。客户端接收到服务端的第二次挥手信号,变为FIN-WAIT-2状态。第二次挥手后,服务端仍可发送数据,客户端仍可接收。

(3)第三次挥手:服务端完成数据传送后,发送FIN标志和ACK标志均为1的报文段,ack=U+1,seq大于V,假设为W,请求断开连接,这一过程称为被动关闭。服务端发送第三次挥手信号后,变为LAST-ACK状态。

(4)第四次挥手:客户端收到第三次挥手信号,随即发送ACK标志为1,seq=U+1,ack=W+1的报文段,变为TIME-WAIT状态。服务端收到第四次挥手信号,变为CLOSED状态。客户端从变为TIME-WAIT状态开始计时,等待2MSL(2倍最大报文时长,约定值)后进入CLOSED状态。四次挥手结束。

综上就是一些理论基础知识的支撑,但是我并不想大章篇幅的去概述这些理论,最终都是要实践,接下来我会着重在代码操作上,谢谢。

2.3 基于TCP协议-只接受一个连接的范例程序

1)服务端(single_conn_server.c)

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <unistd.h>

#define handle_error(cmd, result) \
    if (result < 0)               \
    {                             \
        perror(cmd);              \
        return -1;                \
    }

void *read_from_client(void *argv)
{
    int client_fd = *(int *)argv;
    char *read_buf = NULL;
    ssize_t count = 0;

    read_buf = malloc(sizeof(char) * 1024);
    if (!read_buf)
    {
        perror("malloc server read_buf");
        return NULL;
    }

    while ((count = recv(client_fd, read_buf, 1024, 0)))
    {
        if (count < 0)
        {
            perror("recv");
        }
        fputs(read_buf, stdout);
    }

    printf("客户端请求关闭连接......\n");
    free(read_buf);

    return NULL;
}

void *write_to_client(void *argv)
{
    int client_fd = *(int *)argv;
    char *write_buf = NULL;
    ssize_t send_count = 0;

    write_buf = malloc(sizeof(char) * 1024);
    if (!write_buf)
    {
        printf("写缓存分配失败,断开连接\n");
        shutdown(client_fd, SHUT_WR);
        perror("malloc server write_buf");
        return NULL;
    }
    while (fgets(write_buf, 1024, stdin) != NULL)
    {
        send_count = send(client_fd, write_buf, 1024, 0);
        if (send_count < 0)
{
            perror("send");
        }
    }

    printf("接收到命令行的终止信号,不再写入,关闭连接......\n");
    shutdown(client_fd, SHUT_WR);
    free(write_buf);

    return NULL;
}

int main(int argc, char const *argv[])
{
    int sockfd, temp_result, client_fd;
    pthread_t pid_read, pid_write;

    struct sockaddr_in server_addr, client_addr;

    memset(&server_addr, 0, sizeof(server_addr));
    memset(&client_addr, 0, sizeof(client_addr));

    // 声明IPV4通信协议
    server_addr.sin_family = AF_INET;
    // 我们需要绑定0.0.0.0地址,转换成网络字节序后完成设置
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // 端口随便用一个,但是不要用特权端口
    server_addr.sin_port = htons(6666);

    // 创建server socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    handle_error("socket", sockfd);

    // 绑定地址
    temp_result = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    handle_error("bind", temp_result);

    // 进入监听模式
    temp_result = listen(sockfd, 128);
    handle_error("listen", temp_result);

    // 接受第一个client连接
    socklen_t cliaddr_len = sizeof(client_addr);
    client_fd = accept(sockfd, (struct sockaddr *)&client_addr, &cliaddr_len);
    handle_error("accept", client_fd);

    printf("与客户端 from %s at PORT %d 文件描述符 %d 建立连接\n",
           inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), client_fd);

    // 启动一个子线程,用来读取客户端数据,并打印到 stdout
    pthread_create(&pid_read, NULL, read_from_client, (void *)&client_fd);
    // 启动一个子线程,用来从命令行读取数据并发送到客户端
    pthread_create(&pid_write, NULL, write_to_client, (void *)&client_fd);

    // 阻塞主线程
    pthread_join(pid_read, NULL);
    pthread_join(pid_write, NULL);

    printf("释放资源\n");
    close(client_fd);
    close(sockfd);

    return 0;
}

2)客户端(single_conn_client.c)

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

// 192.168.10.150 IP 地址的16进制表示
#define INADDR_LOCAL 0xC0A80A96

#define handle_error(cmd, result) \
    if (result < 0)               \
    {                             \
        perror(cmd);              \
        return -1;                \
    }

void *read_from_server(void *argv)
{
    int sockfd = *(int *)argv;
    char *read_buf = NULL;
    ssize_t count = 0;

    read_buf = malloc(sizeof(char) * 1024);
    if (!read_buf)
    {
        perror("malloc client read_buf");
        return NULL;
    }

    while (count = recv(sockfd, read_buf, 1024, 0))
    {
        if (count < 0)
        {
            perror("recv");
        }
        fputs(read_buf, stdout);
    }

    printf("收到服务端的终止信号......\n");
    free(read_buf);

    return NULL;
}

void *write_to_server(void *argv)
{
    int sockfd = *(int *)argv;
    char *write_buf = NULL;
    ssize_t send_count = 0;

    write_buf = malloc(sizeof(char) * 1024);

    if (!write_buf)
    {
        printf("写缓存分配失败,断开连接\n");
        shutdown(sockfd, SHUT_WR);
        perror("malloc client write_buf");

        return NULL;
    }

    while (fgets(write_buf, 1024, stdin) != NULL)
    {
        send_count = send(sockfd, write_buf, 1024, 0);
        if (send_count < 0)
        {
            perror("send");
        }
    }

    printf("接收到命令行的终止信号,不再写入,关闭连接......\n");
    shutdown(sockfd, SHUT_WR);
    free(write_buf);

    return NULL;
}

int main(int argc, char const *argv[])
{
    int sockfd, temp_result;
    pthread_t pid_read, pid_write;

    struct sockaddr_in server_addr, client_addr;

    memset(&server_addr, 0, sizeof(server_addr));
    memset(&client_addr, 0, sizeof(client_addr));

    server_addr.sin_family = AF_INET;
    // 连接本机 127.0.0.1
    server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    // 连接端口 6666
    server_addr.sin_port = htons(6666);

    client_addr.sin_family = AF_INET;
    // 连接本机 192.168.10.150
    client_addr.sin_addr.s_addr = htonl(INADDR_LOCAL);
    // 连接端口 8888
    client_addr.sin_port = htons(8888);

    // 创建socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
 handle_error("socket", sockfd);

    temp_result = bind(sockfd, (struct sockaddr *)&client_addr, sizeof(client_addr));
    handle_error("bind", temp_result);

    // 连接server
    temp_result = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    handle_error("connect", temp_result);

    // 启动一个子线程,用来读取服务端数据,并打印到 stdout
    pthread_create(&pid_read, NULL, read_from_server, (void *)&sockfd);
    // 启动一个子线程,用来从命令行读取数据并发送到服务端
    pthread_create(&pid_write, NULL, write_to_server, (void *)&sockfd);

    // 阻塞主线程
    pthread_join(pid_read, NULL);
    pthread_join(pid_write, NULL);

    printf("关闭资源\n");
    close(sockfd);

    return 0;
}

在上述例程中,我们将客户端绑定到了192.168.10.150的8888端口,192.168.10.150实际上是本机IP,此处等价于localhost或127.0.0.1。此外,通常服务端不需要绑定到具体的IP和端口,如果不绑定,启动后会操作系统会随机为客户端分配本机的某个端口。我们这里将客户端绑定至指定的IP和端口,主要是为了在分析时便于区分客户端和服务端,实际的客户端程序完全可以省去这一步。

未完待续。。。2024-08-23.。。。

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

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

相关文章

装过mr又卸载了,max报错 mrmateralattribs missing dlls

rendering>scene converter 打开对话框后&#xff0c;current preset 中选择 remove invalid legacy elements&#xff0c;取消open scene converter。。勾选 automaticaly remove missing。再点 convet scene

HTML静态网页成品作业(HTML+CSS)——个人介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

java-Spring框架02

1.AOP 1.概述 AOP &#xff08;Aspect Oriented Programming&#xff09;&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。&#xff08;是对面向对象编程的补充延续&#xff0c;&#xff09; 面向切面编程思想&#…

Linux之ip命令详解

华子目录 1.ip命令是什么1.1ip命令的由来1.2ip命令的安装包1.2ip选项&#xff08;基本不用&#xff09; 2.查看网络信息2.1显示全部网络接口信息2.2显示单个网络接口信息2.3显示单个接口状态2.4查看路由表2.5查看arp缓存 3.设置网卡ip地址3.1启用或停用网卡3.2设置默认网关3.3新…

【数据集】遥感影像建筑物提取论文常用数据集

几个常用于遥感影像建筑物对比试验的数据集 WHU building dataset 下载链接&#xff1a; https://study.rsgis.whu.edu.cn/pages/download/building_dataset.html WHU数据集中包含多个子数据集&#xff1a; Aerial imagery dataset 航空影像建筑物数据集 数量&#xff1a;8…

SD3337C 恒流Boost DC/DC转换器的白色LED驱动器芯片IC

一般描述 SD3337C是一款升压型DC/DC转换器&#xff0c;具有恒定电流&#xff0c;可驱动白色LED或类似器件。该 器件可以从锂离子电池驱动多达八个串联的LED。LED电流由外部电阻器(RsET)设置&#xff0c;并由反馈(FB)电压(典型值:200mV)直接调节&#xff0c;该电压跨接在…

IntelliJ IDEA使用内网穿透工具配置的公网地址远程连接本地MySQL

文章目录 前言1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql5. 固定连接公网地址6. 固定地址连接测试 前言 本教程主要介绍如何使用Cpolar内网穿透工具实现在IDEA中也可以远程访问家里或者公司的数据库&#xff0c;提高开发效率&#xff01;无…

Stable Diffusion 使用详解(9)--- 字体及背景融入

目录 背景 方法一 利用controlNet lineart invert depth 提示词 效果 方法二 准备蒙版 绘制大型场景艺术字 controlnet Lora 模型 效果 PS 融入 背景 如果看过上一期你应该知道如何利用layer diffusion 制作场景动漫海报&#xff0c;其实掌握这个方法后&#xf…

Java 入门指南:初识 Java NIO

NIO 的引入 在传统的 Java I/O 模型&#xff08;BIO&#xff09;中&#xff0c;I/O 操作是以阻塞的方式进行的。当一个线程执行一个 I/O 操作时&#xff0c;它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈&#xff0c;因为需要为每个连接创建一…

【Three.js基础学习】20.Environment map

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程回顾&#xff1a; 模型的加载 GLTFLoader 环境贴图实现&#xff1b; CubeTextureLoader LDR:低动态范围 backgroundBlurriness&#xff1a;设置背景模糊 (不生效 为…

CSND文章质量分批量查询

简介 CSDN 质量分是一项公开的 CSDN 博文内容质量分析服务&#xff0c;其综合分析了内容的标题、段落结构、正文长度、代码格式及复杂度、链接和超文本内容比例及质量等因素&#xff0c;为 IT 技术文章提供客观公共的质量分析结果 用途 可用与对文章质量做评估可申请创作者 …

更新RK3588开发板的rknn_server和librknnrt.so【这篇文章是RKNPU2从入门到实践 --- 【5】的配套文章】

作者使用的平台有&#xff1a; 一台装有Windows系统的宿主机&#xff0c;在该宿主机上装有Ubuntu 20.04虚拟系统&#xff1b; 瑞芯微RK3588开发板&#xff0c;开发板上的系统为Ubuntu22.04系统&#xff1b; 更新板子的 rknn_server 和 librknnrt.so&#xff0c;rknn_server 和…

Facebook AI的应用前景:如何利用人工智能提升平台功能

人工智能&#xff08;AI&#xff09;正迅速改变我们与社交网络互动的方式。作为全球领先的社交媒体平台之一&#xff0c;Facebook&#xff08;现Meta&#xff09;正通过多种AI技术提升其平台功能。本文将探讨Facebook AI的应用前景&#xff0c;展示如何利用这些技术优化用户体验…

OHIF Viewers 项目介绍

项目结构 项目架构 │ ├── extensions │ ├── default # 默认功能 │ ├── cornerstone # 使用 Cornerstonejs 处理 2D/3D 图像 │ ├── cornerstone-dicom-sr # 结构化报告 (DICOM SR) │ ├── measurement-tracking # 测量追…

备战秋招60天算法挑战,Day28

题目链接&#xff1a; https://leetcode.cn/problems/climbing-stairs/ 视频题解&#xff1a; https://www.bilibili.com/video/BV1h1421t7W3/ LeetCode 70.爬楼梯 题目描述 假设你正在爬楼梯。需要n阶你才能到达楼顶。 每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到…

Nacos2.4.0兼容达梦数据库

这段时间公司在搞国产化&#xff0c;发现当前的nacos版本只支持MySQL和derby数据库&#xff0c;后来翻看官方文档以后&#xff0c;官方文档说2.2以后支持达梦数据库了&#xff0c;但是需要插件。 按照他的思路再结合其他资料&#xff0c;我们开始搞起来&#xff01; 一、下载…

【SpringCloud应用框架】GateWay异步非阻塞模型

Spring Cloud Alibaba 之 GateWay工作流程GateWay搭建 文章目录 一、GateWay工作流程工作流程的核心点总结 二、GateWay搭建 一、GateWay工作流程 流程图如下&#xff1a; 核心概念&#xff1a; 客户端向 Spring Cloud Gateway 发出请求。如果Gateway Handler Mapping确定请…

2024年世界机器人大会精彩回顾-人形机器人的天下

8 月 25 日&#xff0c; 2024 世界机器人大会在北京北人亦创国际会展中心闭幕。本次大会以“共育新质生产力 共享智能新未来”为主题&#xff0c;同期举办论坛、博览会、大赛及配套活动&#xff0c;机器人创新新品、应用新场景纷纷亮相。 2024 世界机器人大会分为论坛、博览会、…

qml formLayout实现方式

一、背景 我们制作界面时&#xff0c;通常有表单界面需要制作&#xff0c;如下图&#xff1a; 但是Qt5 是没有 formLayout 的&#xff0c;直到Qt6才有&#xff0c;所以现在 qml 使用 TableView 来实现这个样式 二、实现 enum ComponentType {TitleText,Text,Button,Image} …

开放式耳机漏音有多大?解密最值得购买的五大品牌!

​现在的很多开放式耳机漏音情况已经得到很好的控制了&#xff0c;特别是大品牌的耳机。现在耳机市场上&#xff0c;开放式耳机因为外观时尚、戴着舒服&#xff0c;成了大家日常爱用的热门货。但是&#xff0c;市面上的开放式耳机品牌多得眼花缭乱&#xff0c;质量也是高低不一…