Socket编程用到的函数TCP UDP实例

news2024/12/22 22:06:49

最基本的 Socket 模型

参考这次答应我,一举拿下 I/O 多路复用! (qq.com)

Socket编程详解-CSDN博客

Socket是一种通信机制,通过它可以在不同主机之间进行数据交换。在Socket编程中,有两种常见的通信模式:客户端-服务器模式点对点模式。它基于TCP/IP协议栈,并使用IP地址端口号来标识通信的目标。

Socket  的中文名叫作套接字,欲建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接。因此可以用Socket来描述网络连接的一对一关系。很像弄了一根网线,一头插在客户端,一头插在服务端,然后进行通信。“IP地址+端口号”就对应一个socket。

在网络通信中,套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文件描述符索发送缓冲区和接收缓冲区。

服务端首先调用socket()函数,创建网络协议为 IPv4,以及传输协议为 TCP 的 Socket ,接着调用bind()函数,给这个 Socket 绑定一个 IP 地址和端口,绑定这两个的目的是什么?

  • 绑定端口的目的:当内核收到 TCP 报文,通过 TCP 头里面的端口号,来找到我们的应用程序,然后把数据传递给我们。

  • 绑定 IP 地址的目的:一台机器是可以有多个网卡的,每个网卡都有对应的 IP 地址,当绑定一个网卡时,内核在收到该网卡上的包,才会发给我们;

绑定完 IP 地址和端口后,就可以调用listen()函数进行监听,此时对应 TCP 状态图中的 listen,如果我们要判定服务器中一个网络程序有没有启动,可以通过 netstate 命令查看对应的端口号是否有被监听。

服务端进入了监听状态后,通过调用accept()函数,来从内核获取客户端的连接,如果没有客户端连接,则会阻塞等待客户端连接的到来。

那客户端是怎么发起连接的呢?客户端在创建好 Socket 后,调用connect()函数发起连接,该函数的参数要指明服务端的 IP 地址和端口号,然后万众期待的 TCP 三次握手就开始了。

在  TCP 连接的过程中,服务器的内核实际上为每个 Socket 维护了两个队列:

  • 一个是还没完全建立连接的队列,称为 TCP 半连接队列,这个队列都是没有完成三次握手的连接,此时服务端处于syn_rcvd的状态;

  • 一个是一件建立连接的队列,称为 TCP 全连接队列,这个队列都是完成了三次握手的连接,此时服务端处于established状态;

当 TCP 全连接队列不为空后,服务端的accept()函数,就会从内核中的 TCP 全连接队列里拿出一个已经完成连接的  Socket 返回应用程序,后续数据传输都用这个 Socket。

注意,监听的 Socket 和真正用来传数据的 Socket 是两个:

  • 一个叫作监听 Socket

  • 一个叫作已连接 Socket

连接建立后,客户端和服务端就开始相互传输数据了,双方都可以通过read()write()函数来读写数据。

至此, TCP 协议的 Socket 程序的调用过程就结束了

基于 Linux 一切皆文件的理念,在内核中 Socket 也是以「文件」的形式存在的,也是有对应的文件描述符(内核可以通过文件描述符找到对应打开的文件)

相关知识

参考CC++ socket网络编程扫盲篇_c++端口号的数据类型-CSDN博客

大小端存储

大小端是针对非单字节数据的存取,比如short型,int型等。大端存储是将数据的高位存储在内存的低地址处,小端存储是将数据的低位存储在内存的低地址处。

为什么会有大小端?

        简单点说就是硬件厂商各有所好,并没有统一的约定制作制作哪一个,大端的优势在于第一个字节就是高位,很容易判断正负性。小端的优势在于第一个字节是低位,最后一个字节是高位,可以依次取出相应的字节进行运算,并且最终会把符号位刷新,这样运算起来更高效。

       内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分。网络数据流同样有大端小端之分,那么如何定义网络数据流的地址呢?发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存,因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。

TCP/IP协议规定:网络数据流应采用大端字节序,即低地址高字节。

IP地址(IP Address)

计算机分布在世界各地,要想和它们通信,必须要知道确切的位置。确定计算机位置的方式有多种,IP 地址是最常用的,例如,114.114.114.114 是国内第一个、全球第三个开放的 DNS 服务地址,127.0.0.1 是本机地址。

其实,我们的计算机并不知道 IP 地址对应的地理位置,当要通信时,只是将 IP 地址封装到要发送的数据包中,交给路由器去处理。路由器有非常智能和高效的算法,很快就会找到目标计算机,并将数据包传递给它,完成一次单向通信。

目前大部分软件使用 IPv4 地址,但 IPv6 也正在被人们接受,尤其是在教育网中,已经大量使用。

端口(Port)

有了 IP 地址,虽然可以找到目标计算机,但仍然不能进行通信。一台计算机可以同时提供多种网络服务,例如Web服务、FTP服务(文件传输服务)、SMTP服务(邮箱服务)等,仅有 IP 地址,计算机虽然可以正确接收到数据包,但是却不知道要将数据包交给哪个网络程序来处理,所以通信失败。

为了区分不同的网络程序,计算机会为每个网络程序分配一个独一无二的端口号(Port Number),例如,Web服务的端口号是 80,FTP 服务的端口号是 21,SMTP 服务的端口号是 25。

端口(Port)是一个虚拟的、逻辑上的概念。可以将端口理解为一道门,数据通过这道门流入流出,每道门有不同的编号,就是端口号。如下图所示:

协议(Protocol)

协议(Protocol)就是网络通信的约定,通信的双方必须都遵守才能正常收发数据。协议有很多种,例如 TCP、UDP、IP 等,通信的双方必须使用同一协议才能通信。协议是一种规范,由计算机组织制定,规定了很多细节,例如,如何建立连接,如何相互识别等。

协议仅仅是一种规范,必须由计算机软件来实现。例如 IP 协议规定了如何找到目标计算机,那么各个开发商在开发自己的软件时就必须遵守该协议,不能另起炉灶。

所谓协议族(Protocol Family),就是一组协议(多个协议)的统称。最常用的是 TCP/IP 协议族,它包含了 TCP、IP、UDP、Telnet、FTP、SMTP 等上百个互为关联的协议,由于 TCP、IP 是两种常用的底层协议,所以把它们统称为 TCP/IP 协议族。

数据传输方式

计算机之间有很多数据传输方式,各有优缺点,常用的有两种:SOCK_STREAM(使用TCP协议)SOCK_DGRAM(使用UDP协议)

SOCK_STREAM 表示面向连接的数据传输方式。数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送,但效率相对较慢。常见的 http 协议就使用 SOCK_STREAM 传输数据,因为要确保数据的正确性,否则网页不能正常解析。
SOCK_DGRAM 表示无连接的数据传输方式。计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。因为 SOCK_DGRAM 所做的校验工作少,所以效率比 SOCK_STREAM 高。

QQ 视频聊天和语音聊天就使用 SOCK_DGRAM 传输数据,因为首先要保证通信的效率,尽量减小延迟,而数据的正确性是次要的,即使丢失很小的一部分数据,视频和音频也可以正常解析,最多出现噪点或杂音,不会对通信质量有实质的影响。

注意:SOCK_DGRAM 没有想象中的糟糕,不会频繁的丢失数据,数据错误只是小概率事件。

有可能多种协议使用同一种数据传输方式,所以在 socket 编程中,需要同时指明数据传输方式和协议。

综上所述:IP地址和端口能够在广袤的互联网中定位到要通信的程序,协议和数据传输方式规定了如何传输数据,有了这些,两台计算机就可以通信了。

Socket编程基本步骤

参考Socket编程详解:从基本概念到实例应用(TCP|UDP C语言实例详解)-CSDN博客

常用函数的原型和参数用法详解:

要使用Socket函数之前要先包含两个头文件

#include <sys/types.h>

#include <socket.h>

1.socket()函数

int socket(int domain, int type, int protocol);
domain:地址族,通常为AF_INET(IPv4)或AF_INET6(IPv6)。
type:套接字类型,可以是SOCK_STREAM(TCP)或SOCK_DGRAM(UDP)。
protocol:协议,通常为0,表示自动选择合适的协议。

2.bind()函数

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd:套接字描述符。
addr:指向本地地址结构体的指针。
addrlen:地址结构体的长度。

3.listen()函数

int listen(int sockfd, int backlog);
sockfd:套接字描述符。
backlog:待连接队列的最大长度。

4.accept()函数

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd:套接字描述符。
addr:指向客户端地址结构体的指针,用于存储客户端的地址信息。
addrlen:指向地址结构体长度的指针。

5.connect()函数

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd:套接字描述符。
addr:指向目标地址结构体的指针。
addrlen:地址结构体的长度。

6.send()函数

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
sockfd:套接字描述符。
buf:指向要发送数据的缓冲区的指针。
len:要发送的数据的长度。
flags:发送标志,通常为0。

7.recv()函数

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sockfd:套接字描述符。
buf:指向接收数据的缓冲区的指针。
len:要接收的数据的最大长度。
flags:接收标志,通常为0。

8.sendto()函数

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
sockfd:套接字描述符。
buf:指向要发送数据的缓冲区的指针。
len:要发送的数据的长度。
flags:发送标志,通常为0。
dest_addr:指向目标地址结构体的指针。
addrlen:目标地址结构体的长度。

9.recvfrom()函数

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
sockfd:套接字描述符。
buf:指向接收数据的缓冲区的指针。
len:要接收的数据的最大长度。
flags:接收标志,通常为0。
src_addr:指向源地址结构体的指针,用于存储源地址信息。
addrlen:指向地址结构体长度的指针。

10.close()函数

int close(int sockfd);
sockfd:套接字描述符。

通过使用这些函数,可以实现TCP和UDP通信的服务器端和客户端程序。TCP提供可靠的、面向连接的通信,适用于需要确保数据可靠性和顺序性的场景,而UDP提供无连接的通信,适用于实时性要求较高但可靠性要求较低的场景。

TCP开发流程:

1.服务器端:

  • 创建套接字:int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
  • 绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
  • 监听连接:listen(serverSocket, backlog);
  • 接受连接:struct sockaddr_in clientAddress; int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
  • 发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
  • 关闭连接:close(clientSocket); close(serverSocket);

2.客户端:

  • 创建套接字:int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
  • 连接服务器:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = inet_addr(serverIP); connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
  • 发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
  • 关闭连接:close(clientSocket);

UDP开发流程:

1.服务器端:

  • 创建套接字:int serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
  • 绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
  • 接收和发送数据:recvfrom(serverSocket, buffer, size, 0, (struct sockaddr*)&clientAddress, sizeof(clientAddress)); sendto(serverSocket, buffer, size, 0, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
  • 关闭套接字:close(serverSocket);

2.客户端:

  • 创建套接字:int clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
  • 发送和接收数据:sendto(clientSocket, buffer, size, 0, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); recvfrom(clientSocket, buffer, size, 0, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
  • 关闭套接字:close(clientSocket);

Socket编程实例 

以下是使用C语言通过Socket实现TCP和UDP通信的服务端和客户端通信程序的示例:

TCP通信示例:

服务端(server.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int serverSocket, clientSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    char buffer[BUFFER_SIZE];

    // 创建服务端套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    // 监听连接请求
    if (listen(serverSocket, 5) == -1) {
        perror("Failed to listen");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", SERVER_PORT);

    // 接受客户端连接
    clientAddrLen = sizeof(clientAddr);
    clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
    if (clientSocket == -1) {
        perror("Failed to accept client connection");
        exit(EXIT_FAILURE);
    }

    printf("Client connected: %s\n", inet_ntoa(clientAddr.sin_addr));

    // 接收数据
    memset(buffer, 0, sizeof(buffer));
    if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Client message: %s\n", buffer);

    // 发送响应
    strcpy(buffer, "Hello, Client!");
    if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字
    close(clientSocket);
    close(serverSocket);

    return 0;
}

客户端(client.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int clientSocket;
    struct sockaddr_in serverAddr;
    char buffer[BUFFER_SIZE];

    // 创建客户端套接字
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <=

 0) {
        perror("Failed to set server IP");
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to connect to server");
        exit(EXIT_FAILURE);
    }

    printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);

    // 发送数据
    strcpy(buffer, "Hello, Server!");
    if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(clientSocket);

    return 0;
}

UDP通信示例:

服务端(server.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int serverSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    char buffer[BUFFER_SIZE];

    // 创建服务端套接字
    serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (serverSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", SERVER_PORT);

    // 接收数据
    clientAddrLen = sizeof(clientAddr);
    memset(buffer, 0, sizeof(buffer));
    if (recvfrom(serverSocket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&clientAddr, &clientAddrLen) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Client message: %s\n", buffer);

    // 发送响应
    strcpy(buffer, "Hello, Client!");
    if (sendto(serverSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&clientAddr, clientAddrLen) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字
    close(serverSocket);

    return 0;
}

客户端(client.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int clientSocket;
    struct sockaddr_in serverAddr;
    char buffer[BUFFER_SIZE];

    // 创建客户端套接字


    clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (clientSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <= 0) {
        perror("Failed to set server IP");
        exit(EXIT_FAILURE);
    }

    printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);

    // 发送数据
    strcpy(buffer, "Hello, Server!");
    if (sendto(clientSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    if (recvfrom(clientSocket, buffer, BUFFER_SIZE, 0, NULL, NULL) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(clientSocket);

    return 0;
}

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

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

相关文章

采煤机作业3D虚拟仿真教学线上展示增强应急培训效果

在化工行业的生产现场&#xff0c;安全永远是首要之务。为了加强从业人员的应急响应能力和危机管理能力&#xff0c;纷纷引入化工行业工艺VR模拟培训&#xff0c;让应急演练更加生动、高效。 化工行业工艺VR模拟培训软件基于真实的厂区环境&#xff0c;精确还原了各类事件场景和…

读人工智能全传02图灵测试

1. 图灵测试 1.1. 模仿游戏 1.2. 20世纪40年代末至50年代初&#xff0c;第一台计算机的出现引发了一场公开辩论&#xff0c;辩论主题就是这一现代科学奇迹的潜力如何 1.2.1. 这场辩论中最瞩目的贡献当归属于一本名叫《控制论》的书&#xff0c;由麻省理工学院数学教授诺伯特…

Java | Leetcode Java题解之第214题最短回文串

题目&#xff1a; 题解&#xff1a; class Solution {public String shortestPalindrome(String s) {int n s.length();int[] fail new int[n];Arrays.fill(fail, -1);for (int i 1; i < n; i) {int j fail[i - 1];while (j ! -1 && s.charAt(j 1) ! s.charAt…

PostgreSQL的pg_filedump工具

PostgreSQL的pg_filedump工具 基础信息 OS版本&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a;16.2 pg软件目录&#xff1a;/home/pg16/soft pg数据目录&#xff1a;/home/pg16/data 端口&#xff1a;5777pg_filedump 是一个工具&#x…

【docker】运行阶段遇到的问题

目录 1、查询docker 下挂载了哪些工具 2、docker中的简单命令 3、实际场景应用&#xff08;redis&#xff09; 目前工作中仅用到了redis,所以没有太多经验可以交流&#xff0c;暂时仅将我目前遇到的进行发布。还请见谅。 1、查询docker 下挂载了哪些工具 docker ps -a 或者…

10.SQL注入-http header利用案例

SQL注入-http header利用案例 首先通过登录http头界面,如图所示:登录的信息会被记录到数据库中去&#xff0c;同时使用bp进行抓包分析 将抓包的数据发送repeater里面进行调试 通过useragent进行注入 将useragent对应的数据信息删除掉,输入单引号测试被后台执行报错sql语法…

《安富莱嵌入式周报》第339期:单片机运行苹果早期Mac系统模拟器,2GHz示波器有源探头,下一代矩阵开关面包板,卡片式声音分贝器,HP经典示波器,ReRAM

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版 https://www.bilibili.com/video/BV1Kf421Q7Lh 《安富莱嵌入式周报》第339期&#xff1a;单片机运行苹果早期Ma…

Newport太阳光模拟器MSOL-UV-X使用说明手侧

Newport太阳光模拟器MSOL-UV-X使用说明手侧

如何在《中国科学报》报刊上发表论文?

如何在《中国科学报》报刊上发表论文&#xff1f; 《中国科学报》征稿 中国科学院、中国工程院、国家自然科学基金委员会、中国科学技术协会共同主办报纸 【级别】&#xff1a;国家级 【版面】&#xff1a;不指定版面&#xff0c;理论稿件&#xff0c;无广告字眼 【方向】&…

尚品汇-(十一)

&#xff08;1&#xff09;spu保存 这个页面选择了手机之后&#xff0c;会调用查询分类品牌的接口&#xff0c;显示品牌&#xff0c;在分类品牌中添加了两个品牌后也会在这里显示出来 销售属性名称需要查询base_sale_attr表&#xff1a; 实体类&#xff1a;BaseSaleAttr pac…

前端三件套开发模版——产品介绍页面

今天有空&#xff0c;使用前端三件套html、css、js制作了一个非常简单的产品制作页面&#xff0c;与大家分享&#xff0c;希望可以满足大家应急的需求。本页面可以对产品进行“抢购”、对产品进行介绍&#xff0c;同时可以安排一张产品的高清大图&#xff0c;我也加入了页面的背…

Nordic 52832作为HID 键盘连接配对电视/投影后控制没反应问题的分析和解决

问题现象&#xff1a;我们的一款HID键盘硬件一直都工作的很好&#xff0c;连接配对后使用起来和原装键盘效果差不多&#xff0c;但是后面陆续有用户反馈家里的电视等蓝牙设备配对连接我们的键盘后&#xff0c;虽然显示已连接&#xff0c;但实际上控制不了。设备涉及到了好些品牌…

Golang | Leetcode Golang题解之第213题打家劫舍II

题目&#xff1a; 题解&#xff1a; func _rob(nums []int) int {first, second : nums[0], max(nums[0], nums[1])for _, v : range nums[2:] {first, second second, max(firstv, second)}return second }func rob(nums []int) int {n : len(nums)if n 1 {return nums[0]}…

Tekla Structures钢结构详图设计软件下载;Tekla Structures高效、准确的合作平台

Tekla Structures&#xff0c;它不仅集成了先进的三维建模技术&#xff0c;还融入了丰富的工程实践经验&#xff0c;为设计师、工程师和建筑商提供了一个高效、准确的合作平台。 在建筑项目的整个生命周期中&#xff0c;Tekla Structures都发挥着举足轻重的作用。从规划阶段开始…

部署nginx服务用于浏览服务器目录并实现账号密码认证登录

1、背景&#xff1a; 因公司业务需求&#xff0c;部署一套数据库备份中心服务&#xff0c;但是因为备份的数据库很多&#xff0c;有项目经理要求能经常去查看备份数据库情况及下载备份数据文件的需求。根据该需求&#xff0c;需要在备份数据库的服务器上部署一个nginx服务&…

mac中如何恢复因为破解脚本导致的IDEA无法启动的问题

问题 为了在mac中安装免费的2024版idea&#xff0c;导致下载了一个脚本&#xff0c;使用这个脚本后&#xff0c;但是发现idea还没有破解&#xff0c;相反导致idea无法启动&#xff0c;每次点击&#xff0c;都会弹出“cannot start IDE…” 问题排查 在访达中点击mac的应用程…

实时数仓Hologres OLAP场景核心能力介绍

作者&#xff1a;赵红梅 Hologres PD OLAP典型应用场景与痛点 首先介绍典型的OLAP场景以及在这些场景上的核心痛点&#xff0c;OLAP典型应用场景很多&#xff0c;总结有四类&#xff1a;第一类是BI报表分析类&#xff0c;例如BI报表&#xff0c;实时大屏&#xff0c;数据中台等…

java项目总结2

3.了解Java的内存分配 4.重载 定义&#xff1a;在一个类中&#xff0c;有相同名的&#xff0c;但是却是不同参数&#xff08;返回类型可以不一样&#xff09; 重载的优点&#xff1a; 1.减少定义方法时使用的单词 2.减少调用方法时候的麻烦&#xff08;比如sum的返回两个数的…

云计算【第一阶段(22)】Linux的进程和计划任务管理

目录 一、查看进程 1.1、程序和进程的关系 1.2、查看进程 1.2.1、静态查看进程信息ps ​编辑 1.2.1.1、实验 1.2.2、动态查看进程信息top 1.2.2.1、实验 1.2.2.2、top 命令全屏操作界面快捷键 1.2.3、pgrep根据特定条件查询进程pid信息 1.2.4、pstree命令以树形结构列出…

工程安全监测仪器:振弦采集仪的应用与发展

工程安全监测仪器&#xff1a;振弦采集仪的应用与发展 振弦采集仪是一种常见的工程安全监测仪器&#xff0c;广泛应用于建筑、桥梁、隧道、地铁等工程项目中。它通过监测振弦的振动变化&#xff0c;可以及时发现结构变形或损坏情况&#xff0c;为工程的安全运行提供重要数据支…