当前位置: 首页 > news >正文

Linux基础-socket详解、TCP/UDP

文章目录

  • 一、Socket 介绍
  • 二、Socket 通信模型
  • 三、Socket 常用函数
    • 1 创建套接字
    • 2 绑定套接字
    • 3、监听连接
    • 4、接受连接
    • 5、接收和发送数据
      • 接收数据
      • 发送数据
    • 6、关闭套接字
  • 四、Socket编程试验
    • 1、源码
      • server.c
      • client.c
    • 2、编译:
    • 3、执行结果
  • 五、补充TCP和UDP协议的Socket流程对比
    • 1、TCP 和 和 UDP区别
    • 2、TCP工作流程图
    • 3、UDP工作流程图


一、Socket 介绍

所谓socket通常也称作 “套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过 “套接字” 向网络发出请求或者应答网络请求 。
Socket 是计算机网络编程中一个重要的概念,它是在应用层和传输层之间提供的一种抽象接口,用于实现应用程序之间的数据交换。Socket 允许程序员使用一种通用的接口来访问底层传输协议,如 TCP 和 UDP,以便进行网络通信。
Socket 是一种编程接口,它提供了一种标准化的方式来创建网络连接,并允许应用程序在网络上发送和接收数据。Socket API 提供了一组函数,这些函数可以用于创建和配置套接字,建立连接,发送和接收数据,以及关闭连接等操作。
Socket 包括流式 Socket(基于 TCP)数据报式 Socket(基于 UDP),其中,TCP面向连接,可靠性较高,可实现有序、零差错的传输;而 UDP 不能确保传输的数据按序、及时到达,因此,UDP 主要出现在数据可靠性要求较低的场合。常见的 Socket 编程相关术语进行介绍:

相关术语介绍
IP 地址唯一标识了网络上的一台主机
端口号是一个 16 位数字,用于标识一个应用程序在主机上的具体位置
套接字用于标识一条网络连接的两端,包含 IP 地址和端口号
服务器在网络上提供服务的主机
客户端与服务器进行通信的主机

一 个Socket 主要由5个信息所构成,分别为:协议,本地地址,本地端口号,远地地址,远地端口号。

  • 协议指定了socket所使用的的通讯协议,一般有TCP或者UDP等。
  • 本地IP地址即本地主机的地址。
  • 本地端口号用以和本地运行的其他程序所区分。
  • 远地IP地址即依照网络协议分配给远程主机的网络地址。
  • 远地端口号用以和远程主机运行的其他程序所区分。

二、Socket 通信模型

Socket 编程通常分为两个部分:服务器端和客户端
服务器端监听一个指定的端口,等待客户端连接。一旦客户端连接到服务器端,服务器端将创建一个新的套接字来处理该客户端的请求。服务器可以同时处理多个客户端请求,每个客户端都会有自己的套接字连接。
客户端首先创建一个套接字,然后连接到服务器端的指定 IP 地址和端口号。一旦连接建立,客户端可以通过套接字发送和接收数据。客户端通常是一次性连接,一旦任务完成就关闭套接字。
在这里插入图片描述
Socket 编程可以用于各种不同的应用程序,例如聊天程序、文件传输、在线游戏等。Socket编程还可以用于创建网络服务器,提供 Web 服务、FTP 服务、邮件服务等。

三、Socket 常用函数

socket 编程的系统调用常用函数如下所示:

  • 创建套接字 socket(domain, type, protocol)
  • 绑定套接字 bind(sockfd, addr, addrlen)
  • 监听连接 listen(sockfd, backlog)
  • 接受连接 accept(sockfd, addr, addrlen)
  • 接收和发送数据 recv(sockfd, buf, len, flags)、send(sockfd, buf, len, flags)
  • 关闭套接字 close(sockfd)

1 创建套接字

在 Linux socket 编程中,创建套接字是构建网络应用程序的第一步。套接字可以理解为应用程序和网络之间的桥梁,用于在网络上进行数据的收发和处理。在 Linux 中,可以使用 socket 系统调用创建套接字。该系统调用的原型和所需头文件如下所示:

#include <sys/types.h>
#include <sys/socket.h>
int socket( (int domain, int type, int protocol );

其中,domain 参数指定了套接字的协议族,type 参数指定了套接字的类型,protocol 参数指定了套接字所使用的具体协议。下面分别介绍这三个参数的含义:

  • 协议族
    协议族指定了套接字所使用的协议类型,常用的协议族包括 AF_INET、AF_INET6、AF_UNIX等。其中,AF_INET 表示 IPv4 协议族,AF_INET6 表示 IPv6 协议族,AF_UNIX 表示 Unix 域协议族。
  • 套接字类型
    套接字类型指定了套接字的数据传输方式,常用的套接字类型包括 SOCK_STREAM、SOCK_DGRAM、SOCK_RAW 等。其中,SOCK_STREAM 表示面向连接的流套接字,主要用于可靠传输数据,例如 TCP 协议。SOCK_DGRAM 表示无连接的数据报套接字,主要用于不可靠传输数据,例如 UDP 协议。SOCK_RAW 表示原始套接字,可以直接访问底层网络协议。
  • 协议类型
    协议类型指定了套接字所使用的具体协议类型,常用的协议类型包括 IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP 等。其中,IPPROTO_TCP 表示 TCP 协议,IPPROTO_UDP 表示 UDP协议,IPPROTO_ICMP 表示 ICMP 协议,通常使用 0 表示由系统自动选择适合的协议。
    例如可以使用以下代码创建一个新的套接字:
int sockfd = = socket(AF_INET, SOCK_STREAM, 0);

2 绑定套接字

创建套接字后,需要将其与一个网络地址绑定,以便其他计算机可以访问该套接字。在 Linux系统下,可以使用 bind()系统调用绑定套接字和地址。该系统调用的原型和所需头文件如下所示:

#include <sys/types.h>
#include <sys/socket.h>
int bind( (int sockfd, const struct sockaddr *addr, socklen_t addrlen);

其中,sockfd 参数指定了需要绑定的套接字描述符,addr 参数指定了需要绑定的地址信息,可以是 struct sockaddr_in 或 struct sockaddr_in6 等结构体类型,addrlen 参数指定了地址信息的长度。使用以下代码将套接字和地址绑定:

// bind port 
// 创建一个 sockaddr_in 结构体类型的 servaddr 变量用于存储服务器的地址信息,并将其清零。
struct sockaddr_in bindaddr;
memset (&bindaddr, 0, sizeof(bindaddr);
bindaddr.sin_family = AF_INET;//指定使用 IPv4 协议(AF_INET)
bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地任意可用的 IP 地址(INADDR_ANY)
bindaddr.sin_port = htons(3000);//使用指定的端口号(port)
// 将套接字 listenfd 绑定到指定的地址 bindaddr上,bind() 函数返回值为 0 表示绑定成功
if(0 != bind(listenfd, (struct sockaddr *)&bindaddr, sizeof(bindaddr))) {printf("bind error\n");return -1;
}

在初始化 sockaddr_in 结构体时,用到了以下函数:

  • memset() :用来将 sockaddr_in 结构体的各个成员变量初始化为 0,这是一个常用的初始化方式。其函数原型如下:
 #include <string.h> // s 参数是需要被初始化的内存区域指针,c 参数是填充字符,n 参数是需要填充的内存字节数。void *memset( void *s, int c, size_t n ); 
  • htonsl()和 和 htons():用于将本机字节序的端口号转换为网络字节序的端口号。其函数原型如下:
 #include <arpa/inet.h> 
uint32_t htonl(uint32_t hostlong );
uint16_t htons(uint16_t hostshort);

其中,hostshort 和 hostlong 参数是本机字节序的端口号,函数返回值是网络字节序的端口号。

3、监听连接

绑定套接字后,需要开始监听连接请求,以便其他网络上的客户端能够与该套接字建立连接。这一步骤通常在服务器端完成。在 Linux 系统下,可以使用 listen()系统调用监听套接字。该系统调用的原型如下:

#include <sys/socket.h> 
int listen(int socket, int backlog);

其中,sockfd 参数指定了需要监听的套接字描述符,backlog 参数指定了连接队列的长度,即等待接受的连接数。例如可以使用以下代码开始监听连接.

// start listen
if (listen(listenfd, 2) != 0) {printf("listem error\n");return -1;
}

4、接受连接

当有客户端请求连接时,需要接受该连接并进行处理。在 Linux 系统下,可以使用 accept(),系统调用接受连接请求。该系统调用的原型和所需头文件如下所示:

#include <sys/socket.h>
int accept (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len);

其中,sockfd 参数指定了需要接受连接的套接字描述符,addr 参数用于存储客户端的地址信息,addrlen 参数用于存储地址信息的长度。使用以下代码接受连接请求:

// 定义一个 sockaddr_in 结构体,用于存储客户端的 IP 地址和端口号
struct sockaddr_in clientaddr;
// 定义一个 socklen_t 类型的变量 clientaddrlen ,用于存储客户端地址结构体的长度
socklen_t clientaddrlen = sizeof(clientaddr);// 调用 accept() 系统调用,接受客户端的连接请求,并返回一个新的套接字描述符 connfd,用于与客户端进行通信。
// accept() 函数会阻塞程序,直到有客户端连接到服务器端。
// listenfd 是服务端的监听套接字, clientaddr 是指向 sockaddr_in 结构体的指针,用于存储客户端的地址信息。
// clientaddrlen 是客户端地址结构体的长度,accept() 函数会将实际接受到的客户端地址长度存储到该变量中。
int clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddrlen);
if (clientfd >= 0) { // 判断 accept() 函数的返回值,判断客户端连接是否失败// 处理接收数据} else{printf("accept error\n");
}

5、接收和发送数据

在 Linux socket 编程中,接收和发送数据是套接字编程的核心步骤之一。当套接字绑定并且处于监听状态,已经成功接受了客户端的连接请求后,接下来就是进行数据的收发。下面将详细介绍如何在 Linux 系统中实现接收和发送数据的过程。

接收数据

在接收数据之前,需要先了解数据在网络传输中的一些基本概念。在 TCP 协议中,发送方发送的数据被分割成一个个 TCP 报文段,每个报文段都包含一个 TCP 首部和数据部分。TCP首部中包含了一些控制信息,如序号、确认号、窗口大小等,用来保证数据的可靠传输。而数据部分则是发送方发送的应用层数据,如 HTTP 报文、FTP 文件等。
在 Linux socket 编程中,接收数据的过程分为两步:先接收 TCP 首部,再接收数据部分。具体步骤如下:
(1)创建一个缓冲区用于接收数据。缓冲区的大小一般为数据部分的大小。
(2)调用 recv() 系统调用接收数据。其函数原型和所需头文件如下:

#include <sys/socket.h> 
ssize_t recv(int sockfd, void *buffer, size_t length, int flags );

其中,sockfd 参数是需要接收数据的套接字描述符,buf 参数是用于存储接收数据的缓冲区指针,len 参数是需要接收的数据的最大长度,flags 参数是接收标志,通常为 0。函数返回值为实际接收到的字节数,如果返回值为 0,表示对端已经关闭连接。
(3)在调用 recv() 系统调用时,会先接收 TCP 首部,然后再接收数据部分。如果数据部分比较大,可能需要多次调用 recv() 系统调用才能接收完整的数据。因此,需要使用一个循环来不断接收数据,直到接收到全部数据或者出现错误为止。另外,需要注意的是,recv() 系统调用是一个阻塞调用,即程序会一直等待直到接收到数据或者出现错误才会返回。如果不希望阻塞调用,可以使用非阻塞 I/O 或者多路复用技术。
(4) 处理接收到的数据。在数据接收完成后,需要对接收到的数据进行处理。具体处理方式根据具体的应用场景而定,如将接收到的数据显示在终端上、将数据写入文件等。

发送数据

发送数据的步骤如下:
(1)定义数据缓冲区:需要定义一个用于存储待发送数据的缓冲区,比如 char buf[MAXLINE]。
(2)将数据拷贝到缓冲区:将需要发送的数据拷贝到缓冲区中,可以使用 strcpy()、memcpy() 等函数进行拷贝操作。
(3)使用 send() 函数发送数据:send() 函数用于向已经建立连接的套接字发送数据,其函数原型如下:

#include <sys/socket.h> 
ssize_t send( int sockfd, const void *buf, size_t len, int flags);

函数调用成功将返回发送数据的字节数(返回值为非负数),返回-1 表示发送失败。sockfd 需要发送数据的套接字描述符;buf 待发送数据的缓冲区指针;len 待发送数据的长度;flags 传输标志,通常为 0。

// send data
int ret = send(clientfd, buf, strlen(buf), 0);
if (ret != strlen(buf)){printf("send data error\n");return -1;
}

需要注意的是,send() 函数并不保证一次能够将所有数据都发送出去,如果数据量比较大,可能需要多次调用 send() 函数才能将所有数据发送出去。
(4)判断是否发送完毕:可以通过判断 send() 函数的返回值和待发送数据的长度是否相等来确定是否发送完毕。

6、关闭套接字

关闭套接字是一个非常重要的步骤。当套接字不再需要使用时,应该立即关闭以释放系统资源和避免资源浪费。关闭套接字的步骤非常简单,只需要调用 close() 系统调用即可。close()
系统调用的函数原型如下:

int close( (int sockfd );

其中,sockfd 参数是需要关闭的套接字描述符。函数返回值为 0 表示成功,返回值为 -1表示失败。

四、Socket编程试验

1、源码

server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
// 自定义传输的数据
typedef struct  msgbuf{int id;char str[32];
} msgbuf;int main() {// create socketint listenfd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == listenfd) {printf("create socket error");return -1;}printf("server create socket ok!\n");// bind port // 创建一个 sockaddr_in 结构体类型的 servaddr 变量用于存储服务器的地址信息,并将其清零。struct sockaddr_in bindaddr;memset (&bindaddr, 0, sizeof(bindaddr));bindaddr.sin_family = AF_INET;//指定使用 IPv4 协议(AF_INET)bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地任意可用的 IP 地址(INADDR_ANY)bindaddr.sin_port = htons(3000);//使用指定的端口号(port)// 将套接字 listenfd 绑定到指定的地址 bindaddr上,bind() 函数返回值为 0 表示绑定成功if(0 != bind(listenfd, (struct sockaddr *)&bindaddr, sizeof(bindaddr))) {printf("bind error\n");return -1;}// start listenif (listen(listenfd, 2) != 0) {printf("listem error\n");return -1;}msgbuf socmsg;// 定义一个 sockaddr_in 结构体,用于存储客户端的 IP 地址和端口号struct sockaddr_in clientaddr;// 定义一个 socklen_t 类型的变量 clientaddrlen ,用于存储客户端地址结构体的长度socklen_t clientaddrlen = sizeof(clientaddr);// accept connection// 调用 accept() 系统调用,接受客户端的连接请求,并返回一个新的套接字描述符 connfd,用于与客户端进行通信。// accept() 函数会阻塞程序,直到有客户端连接到服务器端。// listenfd 是服务端的监听套接字, clientaddr 是指向 sockaddr_in 结构体的指针,用于存储客户端的地址信息。// clientaddrlen 是客户端地址结构体的长度,accept() 函数会将实际接受到的客户端地址长度存储到该变量中。int clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddrlen);if (clientfd >= 0) { // 判断 accept() 函数的返回值,判断客户端连接是否失败while (1) {        	socmsg.id = 0;memset(socmsg.str, ' ',sizeof(socmsg.str));// receive dataint ret = recv(clientfd, &socmsg, sizeof(socmsg), 0);if (ret > 0) {printf("recv data from client, data: %d %s\n", socmsg.id, socmsg.str);printf("send data ...\n");// send dataret = send(clientfd, &socmsg, sizeof(socmsg), 0);if (ret != sizeof(socmsg)) {printf("send data error.\n");}} else {// printf("recv data error.\n");sleep(1);}}		close(clientfd);} else{printf("accept error\n");}//close socketclose(listenfd);return 0;
}

client.c

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>typedef struct  msgbuf{int id;char str[32];
} msgbuf;int main(int argc, const char *argv[]) {char *ip = "192.168.1.100"; // 服务器默认的IP,可以改成服务器实际IP// create socketint clientfd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == clientfd) {printf("create socket error");return -1;}printf("client create socket ok!\n");// connect server struct sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;if (argc == 2) { // 如果有输入IP参数,使用输入的IP参数printf("%s\r\n", argv[1]);serveraddr.sin_addr.s_addr = inet_addr(argv[1]);  // 从命令行参数中获取服务器 IP 地址} else {serveraddr.sin_addr.s_addr = inet_addr(ip);}serveraddr.sin_port = htons(3000);if(-1 == connect(clientfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) {printf("connect error\n");return -1;}printf("connect OK\n");msgbuf socmsg;int i =0;while(1) {sleep(1);socmsg.id = i++;memcpy(socmsg.str,"this is my test msg", strlen("this is my test msg"));// send dataint ret = send(clientfd, &socmsg, sizeof(socmsg), 0);if (ret != sizeof(socmsg)){printf("send data error\n");return -1;}printf("send data ok, %d %s\n",socmsg.id, socmsg.str);// receive datasocmsg.id = 0;// socmsg.str[128] = {0};memset(socmsg.str, ' ',sizeof(socmsg.str));ret = recv(clientfd, &socmsg, sizeof(socmsg), 0);if (ret > 0) {printf("receive data from server: %d %s\n", socmsg.id, socmsg.str);} else {printf("receive data error\n");}}// close socketclose(clientfd);return 0;
}

2、编译:

gcc -o server server.c
gcc -o client client.c

如果client是在板子上执行,需要使用板子系统对应的交叉编译器来编译。例如:aarch64-linux-gnu-gcc -o client client.c

3、执行结果

在这里插入图片描述
在这里插入图片描述
本例程只作为一个简单的demo,体验下socket通讯。

五、补充TCP和UDP协议的Socket流程对比

在一般的网络书籍中,网络协议被分为 5 层:
在这里插入图片描述
⚫应用层:它是体系结构中的最高层,直接为用户的应用进程(例如电子邮件、文件传输和终端仿真)提供服务。在因特网中的应用层协议很多,如支持万维网应用的 HTTP 协议,支持电子邮件的 SMTP 协议,支持文件传送的 FTP , DNS,POP3, SNMP, Telnet 等等。
⚫运输层:负责向两个主机中进程之间的通信提供服务。
运输层主要使用以下两种协议:
① 传输控制协议 TCP(Transmission Control Protocol):面向连接的,数据传输的单位是报文段,能够提供可靠的交付。
② 用户数据包协议 UDP(User Datagram Protocol):无连接的,数据传输的单位是用户数据报,不保证提供可靠的交付,只能提供“尽最大努力交付”。
⚫ 网络层:负责将被称为数据包(datagram)的网络层分组从一台主机移动到另一台主机。
⚫ 链路层:因特网的网络层通过源和目的地之间的一系列路由器路由数据报。
⚫ 物理层:在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。
这些层对于初学者来说很难理解,我们只需要知道:我们需要使用“运输层”编写应用程序,我们的应用程序位于“应用层”。使用“运输层”时,可以选择 TCP 协议,也可以选择 UDP 协议。

1、TCP 和 和 UDP区别

TCP 向它的应用程序提供了面向连接的服务。这种服务有 2 个特点:可靠传输、流量控制(即发送方/接收方速率匹配)。它包括了应用层报文划分为短报文,并提供拥塞控制机制。
UDP 协议向它的应用程序提供无连接服务。它没有可靠性,没有流量控制,也没有拥塞控制。
在这里插入图片描述

既然 TCP 提供了可靠数据传输服务,而 UDP 不能提供,那么 TCP 是否总是首选呢?

答案是否定的,因为有许多应用更适合用 UDP,举个例子:视频通话时,使用 UDP,偶尔的丢包、偶尔的花屏时可以忍受的;如果使用 TCP,每个数据包都要确保可靠传输,当它出错时就重传,这会导致后续的数据包被阻滞,视频效果反而不好。使用 UDP 时,有如下特点:
① 关于何时发送什么数据控制的更为精细
采用 UDP 时只要应用进程将数据传递给 UDP,UDP 就会立即将其传递给网络层。而 TCP 有重传机制,而不管可靠交付需要多长时间。但是实时应用通常不希望过分的延迟报文段的传送,且能容忍一部分数据丢失。
② 无需建立连接,不会引入建立连接时的延迟。
③ 无连接状态,能支持更多的活跃客户。
④ 分组首部开销较小。

2、TCP工作流程图

在这里插入图片描述

3、UDP工作流程图

在这里插入图片描述

相关文章:

Linux基础-socket详解、TCP/UDP

文章目录 一、Socket 介绍二、Socket 通信模型三、Socket 常用函数1 创建套接字2 绑定套接字3、监听连接4、接受连接5、接收和发送数据接收数据发送数据 6、关闭套接字 四、Socket编程试验1、源码server.cclient.c 2、编译&#xff1a;3、执行结果 五、补充TCP和UDP协议的Socke…...

【菜单下拉效果】基于jquery实现二级菜单下拉效果(附完整源码下载)

Js菜单下拉特效目录 &#x1f354;涉及知识&#x1f964;写在前面实现效果&#x1f367;一、涉及知识&#x1f333;二、具体实现2.1 搭建一级菜单2.2 搭建二级菜单项2.3 引入js文件2.4 构建CSS文件 &#x1f40b;三、源码获取&#x1f305; 作者寄语 &#x1f354;涉及知识 ht…...

如何使用resource-counter统计跨Amazon区域的不同类型资源数量

关于resource-counter resource-counter是一款功能强大的命令行工具&#xff0c;该工具基于纯Python 3开发&#xff0c;可以帮助广大研究人员跨Amazon区域统计不同类型资源的数量。 该工具在统计完不同区域的各类资源数量后&#xff0c;可以在命令行中输出并显示统计结果。res…...

nextTick的作用与原理

在 Vue 中&#xff0c;nextTick允许我们延迟执行一段代码&#xff0c;直到 Vue完成其当前的 DOM 更新周期。这使得我们可以在 DOM 更新后安全地访问和修改 DOM 元素。 一、Vue 的异步更新策略 Vue 采用了一种称为异步更新策略的机制。这意味着当数据发生变化时&#xff0c;Vue…...

mybatis工程需要的pom.xml,以及@Data 、@BeforeEach、@AfterEach 的使用,简化mybatis

对 “mybatis - XxxMapper.java接口中方法的参数 和 返回值类型&#xff0c;怎样在 XxxMapper.xml 中配置的问题” 这篇文章做一下优化 这个pom.xml文件&#xff0c;就是上面说的这篇文章的父工程的pom.xml&#xff0c;即&#xff1a;下面这个pom.xml 是可以拿来就用的 <?…...

微信小程序demo-----制作文章专栏

前言&#xff1a;不管我们要做什么种类的小程序都涉及到宣传或者扩展其他业务&#xff0c;我们就可以制作一个文章专栏的页面&#xff0c;实现点击一个专栏跳转到相应的页面&#xff0c;页面可以有科普类的知识或者其他&#xff0c;然后页面下方可以自由发挥&#xff0c;添加联…...

Linux migrate_type初步探索

1、基础知识 我们都知道Linux内存组织管理结构架构&#xff0c;顶层是struct pglist_data&#xff0c;然后再到struct zone&#xff0c;最后是struct page。大概的管理结构是这样的&#xff1a; 根据物理内存的地址范围可划分不同的zone&#xff0c;每个zone里的内存由buddy…...

i.MX 6ULL 裸机 IAR 环境安装

一. IAR 的安装请自行搜索 二. 使用最新版本的 IAR&#xff0c;需要修改 SDK 1. 在 SDK 的 core_ca7.h 加上 #include "intrinsics.h" /* IAR Intrinsics */ 2. debug 时需要修改每个工程下的 ddr_init.jlinkscript&#xff0c;参考链接 Solved: How to conn…...

cmake进阶:文件操作

一. 简介 前面几篇文章学习了 cmake的文件操作&#xff0c;写文件&#xff0c;读文件。文章如下&#xff1a; cmake进阶&#xff1a;文件操作之写文件-CSDN博客 cmake进阶&#xff1a;文件操作之读文件-CSDN博客 本文继续学习文件操作。主要学习 文件重命名&#xff0c;删…...

在UI界面中播放视频_unity基础开发教程

在UI界面中播放视频_unity基础开发教程 前言操作步骤结语 前言 之前我写过一篇在场景中播放视频的文章&#xff0c;但是在开发中有时候也会在UI的界面中播放视频&#xff0c;这期我们做一下在UI的界面中播放视频。 操作步骤 首先在场景中创建一个Raw Image&#xff0c;UI->…...

TypeScipt 联合类型 | 号的使用

联合类型有两种使用方法&#xff1a; 一种类型中多个可能的值。具有多种不同的类型中的一种。 一种类型中多个可能的值。 type isAye true | false;const aye:isAye true; const aye1:isAye false; const aye2:isAye 3; // Type number is not assignable to type isAye…...

MATLAB 变换

MATLAB 变换&#xff08;Transforms&#xff09; MATLAB提供了用于处理诸如Laplace和Fourier变换之类的变换的命令。转换在科学和工程中用作简化分析和从另一个角度查看数据的工具。 例如&#xff0c;傅立叶变换允许我们将表示为时间函数的信号转换为频率函数。拉普拉斯变换使…...

【005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放】

005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放 文章目录 005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放创作背景MA120X0P输出模式BTLSEPBTLSEBTL 硬件配置方式/硬件Limiter限幅器限幅器作用过程 主要寄存器操作指令 ma120x0p.cma120x0p.h 创作背景 学历代表过去、能…...

2、​​​​​​​FreeCAD模块与核心架构总结

FreeCAD作为一个开源的3D建模软件&#xff0c;其内部架构由多个模块组成&#xff0c;这些模块共同协作以支持软件的各种功能。本总结将基于提供的参考文档&#xff0c;对FreeCAD的核心模块、架构特性以及启动过程进行翻译和详细阐述。 核心模块概览 FreeCAD的核心模块主要包括…...

MySQL为什么默认引擎是InnoDB?

因为InnoDB特别强大,其支持很多东西 1.支持事务: 意味着对于一个复杂的SQL语句要么全部执行成功,要么全部失败,因为其底层是原子性的 2.支持并发(行级并发) 意味着面对高并发,多个用户可以同时访问一个表的不同行,不同行之间上锁,而不是给一个表上锁,这样就提高了高并发的性能和…...

K8s: Helm搭建mongodb集群(1)

mongodb 集群搭建 mongdb 部署前 需要创建 pvc, pv 和 sc&#xff0c;如果在云上会自动创建helm 应用中心: https://artifacthub.io 1 &#xff09;Helm 安装 mongodb A. 无本地存储配置&#xff0c;重启数据消失 在 https://artifacthub.io/packages/helm/bitnami/mongodb…...

应用分层和企业规范

目录 一、应用分层 1、介绍 &#xff08;1&#xff09;为什么需要应用分层&#xff1f; &#xff08;2&#xff09;如何分层&#xff1f;&#xff08;三层架构&#xff09; MVC 和 三层架构的区别和联系 高内聚&#xff1a; 低耦合&#xff1a; 2、代码重构 controlle…...

Flutter笔记:Widgets Easier组件库(1)使用各式边框

Flutter笔记 Widgets Easier组件库&#xff08;1&#xff09;&#xff1a;使用边框 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…...

OpenHarmony实战开发-上传文件

Web组件支持前端页面选择文件上传功能&#xff0c;应用开发者可以使用onShowFileSelector()接口来处理前端页面文件上传的请求。 下面的示例中&#xff0c;当用户在前端页面点击文件上传按钮&#xff0c;应用侧在onShowFileSelector()接口中收到文件上传请求&#xff0c;在此接…...

外贸企业邮箱是什么?做外贸企业邮箱哪个好?

外贸企业邮箱是什么&#xff1f;外贸企业在进行跨国沟通时必不可少的工具就是外贸企业邮箱&#xff0c;外贸企业邮箱需要具备的条件就是海外邮件抵达率高、安全稳定、多语言沟通。而我们又怎么选择一个适合的外贸企业邮箱呢&#xff1f;小编今天带您一起了解。 一、外贸企业邮…...

写一个简单的程序

思路分析&#xff1a; 1. 导入必要的库 首先&#xff0c;确保你的项目中包含了AWT或Swing库&#xff0c;因为我们将使用它们来创建图形界面。 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import j…...

CentOS安装Docker指南

Docker安装与配置教程 Docker作为一种轻量级的虚拟化技术&#xff0c;在现代软件开发和运维中扮演着重要的角色。下面&#xff0c;我将以技术博主的身份&#xff0c;向大家详细介绍如何在Linux系统上安装和配置Docker&#xff0c;特别是如何设置Docker的监听地址和端口&#x…...

python绘图(pandas)

matplotlib绘图 import pandas as pd abs_path rF:\Python\learn\python附件\pythonCsv\data.csv df pd.read_csv(abs_path, encodinggbk) # apply根据多列生成新的一个列的操作&#xff0c;用apply df[new_score] df.apply(lambda x : x.数学 x.语文, axis1)# 最后几行 …...

Android(Java)项目支持Kotlin语言开发

Android&#xff08;Java&#xff09;项目通过相关Kotlin设置后&#xff0c;允许同时使用Java语言和Kotlin语言进行开发代码的。 示例环境&#xff1a; Android Studio Giraffe | 2022.3.1 Patch 3 Java 8 Kotlin 1.9.20 设置Kotlin选项&#xff1a; 第一步&#xff1a;在项…...

Terraform创建模块

模块就是包含一组Terraform代码的文件夹&#xff0c;可以通过模块直接使用别人编写好的Terraform代码来创建资源。 Terraform模块是编写高质量Terraform代码&#xff0c;提升代码复用性的重要手段&#xff0c;可以说&#xff0c;一个成熟的生产环境应该是由数个可信成熟的模块组…...

《华为鸿蒙:从备胎到主角的崛起之路》

华为鸿蒙操作系统的发展历程可以追溯到 2012 年&#xff0c;当时华为开始规划自有操作系统鸿蒙 OS。然而&#xff0c;直到 2019 年 5 月&#xff0c;鸿蒙才正式进入开发阶段。 2019 年 8 月 9 日&#xff0c;华为正式发布了鸿蒙操作系统。 鸿蒙系统的首个版本是于 2019 年推出…...

FPGA学习笔记(2)——Verilog语法及ModelSim使用

1.1 语法 1、赋值语句 和 < 为阻塞赋值&#xff0c;当该语句结束时&#xff0c;下一个语句才开始执行&#xff0c;串行执行 < 为非阻塞幅值&#xff0c;该语句和整个语句块同时执行&#xff0c;并行执行 1.2 ModelSim使用 1、修改源文件路径&#xff1a;File -> …...

2024年十大AI工具,让你的工作学习效率飞跃

在这个迅速变化的数字时代&#xff0c;人工智能技术正在以前所未有的速度发展和革新。AI技术不仅深入科研、医疗和教育等领域&#xff0c;还广泛应用于日常生活和商业活动中。本文梳理了2024年十款最好用的AI工具&#xff0c;它们各有特色&#xff0c;能极大提升工作效率和生活…...

linux之NAMP

linux之NAMP Nmap&#xff08;Network Mapper&#xff09;是一个开源的网络扫描和安全审计工具。它被设计用来快速地扫描大型网络&#xff0c;尽管它也可以对单个主机进行有效的扫描。Nmap利用原始IP数据包以多种方式探测目标网络上的主机、服务&#xff08;应用程序名称和版本…...

uniapp 禁止截屏(应用内,保护隐私)插件 Ba-ScreenShot

禁止截屏&#xff08;应用内&#xff0c;保护隐私&#xff09; Ba-ScreenShot 简介&#xff08;下载地址&#xff09; Ba-ScreenShot 是一款uniapp禁止应用内截屏的插件&#xff0c;保护隐私&#xff0c;支持禁止截屏、放开截屏 截图展示 也可关注博客&#xff0c;实时更新最…...

内部建设网站需要什么条件/制作一个简单的网站

从SQL SERVER 2008开始&#xff0c;SQL SERVER 提供了对数据进行压缩的功能&#xff0c;启用数据压缩无须修改应用程序。 数据压缩可有效减少数据的占用空间&#xff0c;读取和写入相同数据花费的IO也响应减少&#xff0c;从而可以有效缓解IO压力&#xff0c;但由于数据在读取和…...

哪些网站用python做服务框架/潍坊快速网站排名

影评分析第2篇写在前面 日本电视动画《BORUTO -火影新世代》&#xff08;中国大陆译名《博人传&#xff1a;火影忍者新时代》&#xff09;改编自岸本齐史原作并监修、池本干雄编绘、小太刀右京编剧的同名漫画&#xff0c;是《火影忍者》系列的续篇&#xff0c;讲述原作故事完结…...

青岛企业网站制作公司/网站seo诊断工具

2019独角兽企业重金招聘Python工程师标准>>> 正常来说一个网页中要么全部使用http&#xff0c;要么全部使用https 但是偶尔有些不完善的库自己会写死了调用的链接。 一个简单的方法是在网页的head下加入下面这句 <meta http-equiv"Content-Security-Policy&…...

惠阳网站制作公司/建设网站前的市场分析

Ubuntu操作基本快捷键* 打开主菜单 Alt F1* 运行 Alt F2* 打开终端 AltF2 然后输入gnome-terminal回车* 显示桌面 Ctrl Alt d* 最小化当前窗口 Alt F9* 最大化当前窗口 Alt F10* 关闭当前窗口 Alt F4* 截取全屏 Print Screen* 截取窗口 Alt Print Screen默认特…...

外贸网站做啥/无锡网络公司

{******************************** 版权所有 jack_0424126.com 2006、4、16 功能描述&#xff1a; 备份SQLServer 数据库文件到本地机上 实现思路&#xff1a; 因SQLServer的备份文件只能存储于数据库服务器所在的机器上&#xff0c;为客户端数据备份带来不便。 为突破这…...

网站后台凡科建设/外贸营销网站怎么建站

通过Xtool公司在深圳做XTOOL EZ500测试确定的汽油和柴油车&#xff0c;并提供全系统的诊断和特殊功能&#xff0c;它超越前辈Xtool设备&#xff0c;如Xtool EZ400&#xff0c;Xtool EZ300和X100 PAD。 Xtool EZ500涵盖Xtool EZ400&#xff0c;EZ300和X100 PAD的所有功能&#x…...