嵌入式学习——Linux高级编程复习(TCP编程)——day44

基于TCP聊天:
    clientA.c                     clientB.c 

    socket                                socket 
    connect                              bind 
                                               listen
                                               accept

                                
    pthread_create 
    pthread_create                pthread_create
    pthread_join                    pthread_create
    pthread_join                    pthread_join
                                            pthread_join

1. TCP编程——函数接口

1.1 socket(首先监听套接字)

        1. 定义

              int socket(int domain, int type, int protocol);

        2. 功能

                创建一个用来进程通信的套接字,返回文件描述符

        3. 参数

                domain:AF_INET           IPv4协议族
                type:SOCK_STREAM    流式套接字            tcp传输协议
                        SOCK_DGRAM    数据报套接字            udp传输协议
                        SOCK_RAW        原始套接字            
                protocol:
                        默认为0 

        4. 返回值

                成功返回套接字新文件描述符
                失败返回-1 

        5. 注意

1.2 inet_addr

        1. 定义

              in_addr_t inet_addr(const char *cp);

        2. 功能

                将字符串IP地址转换为二进制IP地址 

        3. 参数

                cp:字符串IP地址空间首地址

        4. 返回值

                成功返回二进制IP地址

        5. 注意

1.3 htons

        1. 定义

              uint16_t htons(uint16_t hostshort);

        2. 功能

                将本地字节序(小端)转换为网络字节序(大端)

        3. 参数

                hostshort:本地端口号

        4. 返回值

                返回网络字节序端口号

        

      uint16_t ntohs(uint16_t netshort);
      功能:
        将网络字节序(大端)转换为本地字节序(小端)

1.4 bind

        1. 定义

              int bind(int sockfd, const struct sockaddr *addr,
                        socklen_t addrlen);

        2. 功能

                将套接字与IP地址端口绑定在一起

        3. 参数

                sockfd:文件描述符 
                addr:结构体空间首地址 
                addrlen:信息的长度

        4. 返回值

                成功返回0 
                失败返回-1 

        5. 注意

1.5 connect

        1. 定义

                  int connect(int sockfd, const struct sockaddr *addr,
                           socklen_t addrlen);

        2. 功能

                    向接收端发送三次握手链接请求

        3. 参数

                    sockfd:文件描述符
                    addr:接收方地址空间首地址
                    addrlen:接收方地址的大小

        4. 返回值

                    成功返回0 
                    失败返回-1 

        5. 注意

1.6 listen

        1. 定义

                  int listen(int sockfd, int backlog);

        2. 功能

                    监听链接请求

        3. 参数

                    sockfd:文件描述符
                    backlog:允许最多等待链接的个数

        4. 返回值

                    成功返回0 
                    失败返回-1 

        5. 注意

1.7 accept(返回通信套接字)

        1. 定义

                  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

        2. 功能

                    处理等待队列中第一个链接

        3. 参数

                    sockfd:文件描述符 
                    addr:存放链接对方地址信息空间首地址
                    addrlen:想要接收地址大小变量空间首地址

        4. 返回值

                    成功返回与发送端建立的新文件描述符(通信套接字)
                    失败返回-1 

        5. 注意

1.8 send (发的太块会阻塞)

        1. 定义

                  ssize_t send(int sockfd, const void *buf, size_t len, int flags);

        2. 功能

                    发送数据

        3. 参数

                    sockfd:文件描述符
                    buf:存放数据空间首地址
                    len:发送数据长度
                    flags:属性 默认为0 

        4. 返回值

                    成功返回发送字节数
                    失败返回-1 

        5. 注意

1.9 recv

        1. 定义

                  ssize_t recv(int sockfd, void *buf, size_t len, int flags);

        2. 功能

                    接收数据

        3. 参数

                    sockfd:文件描述符
                    buf:存放数据空间首地址 
                    len:最多接收数据大小
                    flags:属性 默认为0 

        4. 返回值

                    成功返回实际接收字节数
                    失败返回-1 
                    对方关闭套接字返回0 

        5. 注意

2. TCP示例程序

2.1 TCP单向通信

        (1)头文件

#ifndef _HEAD_H_
#define _HEAD_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <arpa/inet.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

#endif

        (2)makefile

all:send recv

send:send.c
	gcc $^ -o $@
recv:recv.c
	gcc $^ -o $@

        (3)recv.c

#include "head.h"

int main(int argc, char const *argv[])
{
    int confd = 0;
    int listfd = 0;
    int ret_connect = 0;
    int ret_bind = 0;
    int ret_listen = 0;
    struct sockaddr_in recvaddr;
    struct sockaddr_in sendaddr;
    socklen_t addrlen = sizeof(sendaddr);
    ssize_t ret_send = 0;
    ssize_t ret_recv = 0;

    listfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == listfd)
    {
        perror("socket error!\n");
        return -1;
    }

    bzero(&recvaddr,sizeof(recvaddr));
    bzero(&sendaddr,sizeof(sendaddr));

    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");

    ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (-1 == ret_bind)
    {
        perror("bind error!\n");
        return -1;
    }

    ret_listen = listen(listfd, 3);
    if (-1 == ret_listen)
    {
        perror("listen error!\n");
        return -1;     
    }

    confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);
    if (-1 == confd)
    {
        perror("accept error!\n");
        return -1;  
    }

    while (1)
    {
        char buf[256] = {0};
 
        ret_recv = recv(confd, buf, sizeof(buf), 0);
        if (ret_recv <= 0)
        {
            break;
        }

        time_t tm;
        time(&tm);
        sprintf(buf, "%s %s", buf, ctime(&tm));

        ret_send = send(confd, buf, strlen(buf), 0);
        if (-1 == ret_send)
        {
            perror("send error!\n");
            return -1;        
        } 
    }
    
    close(confd);
    close(listfd);

    return 0;
}

        (4)send.c

#include "head.h"

int main(int argc, char const *argv[])
{
    int confd = 0;
    int ret_connect = 0;
    struct sockaddr_in recvaddr;
    socklen_t addrlen = 0;
    ssize_t ret_send = 0;
    ssize_t ret_recv = 0;

    confd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == confd)
    {
        perror("socket error!\n");
        return -1;
    }

    bzero(&recvaddr, sizeof(recvaddr));

    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");

    ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (-1 == ret_connect)
    {
        perror("connect error!\n");
        return -1;        
    }

    while (1)
    {
        char buf[256] = {"supercarrydoinb"};
        ret_send = send(confd, buf, strlen(buf), 0);
        if (-1 == ret_connect)
        {
            perror("send error!\n");
            return -1;        
        }  
        ret_recv = recv(confd, buf, sizeof(buf), 0);
        if (ret_recv <= 0)
        {
            break;
        }

        printf("%s", buf);
        sleep(1);
    }
    
    close(confd);

    return 0;
}

2.2 TCP实现多线程双机聊天(chat)——注意:!!线程编译gcc要加后缀 -lpthread

        (1)头文件

#ifndef _HEAD_H_
#define _HEAD_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <arpa/inet.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

#endif

        (2)makefile

all:send recv

send:send.c
	gcc $^ -o $@ -lpthread
recv:recv.c
	gcc $^ -o $@ -lpthread

        (3)recv.c

#include "head.h"

struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;

void *th1(void *arg)
{
    int confd = *(int *)arg;
    ssize_t ret_recv = 0;
    while (1)
    {
        char buf[256] = {0};
        ret_recv = recv(confd, buf, sizeof(buf), 0);
        if (-1 == ret_recv)
        {
            perror("recv error!\n");
        }
        printf("from recv: %s\n", buf);
    }
}

void *th2(void *arg)
{
    int confd = *(int *)arg;
    ssize_t ret_send = 0;
    while (1)
    {
        printf("to recv:");
        char buf[256] = {0};
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = '\0';
        ret_send= send(confd, buf, strlen(buf), 0);
        if (-1 == ret_send)
        {
            perror("send error!\n");
        }
    }
}

int main(int argc, char const *argv[])
{
    int confd = 0;
    int ret_connect = 0;
    socklen_t addrlen = sizeof(sendaddr);
    ssize_t ret_recv = 0;
    ssize_t ret_send = 0;
    pthread_t tid1;
    pthread_t tid2;
    char buf[256] = {0};

    confd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == confd)
    {
        perror("socket error!\n");
        return -1;
    }

    bzero(&recvaddr, sizeof(recvaddr));
    bzero(&sendaddr, sizeof(sendaddr));

    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");

    ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (-1 == ret_connect)
    {
        perror("connect error!\n");
        return -1;
    }
    
#if 0
    ret_recv = recv(confd, buf, sizeof(buf), 0);
    if (-1 == ret_recv)
    {
        perror("recv error!\n");
        return -1;
    }
#endif

    pthread_create(&tid1, NULL, th1, &confd);
    pthread_create(&tid2, NULL, th2, &confd);

    pthread_join(tid1, NULL);
    pthread_join(tid1, NULL);
    
    return 0;
}

        (4)send.c

#include "head.h"

struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;

void *th1(void *arg)
{
    int confd = *(int *)arg;
    ssize_t ret_recv = 0;
    while (1)
    {
        char buf[256] = {0};
        ret_recv = recv(confd, buf, sizeof(buf), 0);
        if (-1 == ret_recv)
        {
            perror("recv error!\n");
        }
        printf("from send: %s\n", buf);
    }
}

void *th2(void *arg)
{
    int confd = *(int *)arg;
    ssize_t ret_send = 0;
    while (1)
    {
        printf("to send:");
        char buf[256] = {0};
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = '\0';
        ret_send = send(confd, buf, strlen(buf), 0);
        if (-1 == ret_send)
        {
            perror("send error!\n");
        }
    }
}

int main(int argc, char const *argv[])
{
    int listfd = 0;
    int confd = 0;
    int ret_bind = 0;
    int ret_listen = 0;
    socklen_t addrlen = sizeof(sendaddr);
    ssize_t ret_recv = 0;
    ssize_t ret_send = 0;
    pthread_t tid1;
    pthread_t tid2;
    char buf[256] = {0};

    listfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == listfd)
    {
        perror("socket error!\n");
        return -1;
    }

    bzero(&recvaddr, sizeof(recvaddr));
    bzero(&sendaddr, sizeof(sendaddr));

    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");

    ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (-1 == ret_bind)
    {
        perror("bind error!\n");
        return -1;
    }

    ret_listen = listen(listfd, 3);
    if (-1 == ret_listen)
    {
        perror("listen error!\n");
        return -1;        
    }

    confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);
    if (-1 == confd)
    {
        perror("accept error!\n");
        return -1;         
    }
    
#if 0
    ret_recv = recv(confd, buf, sizeof(buf), 0);
    if (-1 == ret_recv)
    {
        perror("recv error!\n");
        return -1;
    }
#endif

    pthread_create(&tid1, NULL, th1, &confd);
    pthread_create(&tid2, NULL, th2, &confd);

    pthread_join(tid1, NULL);
    pthread_join(tid1, NULL);
    
    return 0;
}

2.3 TCP实现文件的传输(结构体)

        (1)头文件

#ifndef _HEAD_H_
#define _HEAD_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <arpa/inet.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

#endif

        (2)makefile

all:send recv

send:send.c
	gcc $^ -o $@ -lpthread
recv:recv.c
	gcc $^ -o $@ -lpthread

        (3)recv.c

#include "head.h"

typedef struct 
{
    char buf[1024];
    char filename[32];
    int rd_ret;
    int total;
}MSG;

int main(int argc, char const *argv[])
{
    int ret_connect = 0;
    int ret_stat = 0;
    int confd = 0;
    int openfd = 0;
    ssize_t ret_recv = 0;
    ssize_t ret_send = 0;
    struct sockaddr_in recvaddr;
    MSG msg;
    struct stat st;

    confd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == confd)
    {
        perror("socket error!\n");
        return -1;
    }

    bzero(&recvaddr, sizeof(recvaddr));
    bzero(&msg, sizeof(msg));

    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");

    ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (-1 == ret_connect)
    {
        perror("connetc error!\n");
        return -1;
    }

    openfd = open("./1.png", O_RDONLY);
    if (-1 == openfd)
    {
        perror("open error!\n");
        return -1;
    }

    strcpy(msg.filename, "2.png");

    ret_stat = stat("./1.png", &st);
    if (-1 == ret_stat)
    {
        perror("stat error!\n");
        return -1;
    }
    msg.total = st.st_size;

    while (1)
    {
        bzero(msg.buf, sizeof(msg.buf));

        msg.rd_ret = read(openfd, msg.buf, sizeof(msg.buf));
        send(confd, &msg, sizeof(msg), 0);
        if (msg.rd_ret <= 0)
        {
            break;
        }
        char buf[256] = {0};
        ret_recv = recv(confd, buf, sizeof(buf), 0);
        if (ret_recv <= 0)
        {
            break;
        }
        usleep(1000 * 200);
    }

    close(confd);
    close(openfd);

    return 0;
}

        (4)send.c

#include "head.h"

typedef struct 
{
    char buf[1024];
    char filename[32];
    int rd_ret;
    int total;
}MSG;

int main(int argc, char const *argv[])
{
    int listfd = 0;
    int ret_bind = 0;
    int ret_listen = 0;
    int confd = 0;
    ssize_t ret_recv = 0;
    ssize_t ret_send = 0;
    struct sockaddr_in recvaddr;
    struct sockaddr_in sendaddr;
    socklen_t addrlen = sizeof(sendaddr);
    MSG msg;

    listfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == listfd)
    {
        perror("socket error!\n");
        return -1;
    }

    bzero(&recvaddr, sizeof(recvaddr));
    bzero(&sendaddr, sizeof(sendaddr));
    bzero(&msg, sizeof(msg));

    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");

    ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (-1 == ret_bind)
    {
        perror("bind error!\n");
        return -1;
    }


    ret_listen = listen(listfd, 3);
    if (-1 == ret_listen)
    {
        perror("listen error!\n");
        return -1;
    }

    confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);
    if (-1 == confd)
    {
        perror("accept error!\n");
        return -1;
    }

    int openfd = 0;
    int flag = 0;
    int total = 0;
    int current_size = 0;
    while (1)
    {
        ret_recv = recv(confd, &msg, sizeof(msg), 0);
        if (ret_recv <= 0)
        {
            break;
        }

        if (0 == msg.rd_ret)
        {
            printf("file upload end\n");
            return -1;
        }

        if (0 == flag)//拿到文件总大小
        {
            openfd = open(msg.filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
            if (-1 == openfd)
            {
                perror("open error!\n");
                return -1;
            }

            flag = 1;
            total = msg.total;
        }

        write(openfd, msg.buf, msg.rd_ret);
        current_size += msg.rd_ret;
        printf("%d / %d\n", current_size, total);
        char buf[256] = "go on";
        send(confd, buf, strlen(buf), 0);
    }

    close(confd);
    close(openfd);
    close(listfd);

    return 0;
}

3. TCP机制

    1.序列号:发送字节内容在缓存区中的编号(要发送字节的编号)
    2.确认号:收到字节内容的编号(只有ACK为1时才有确认号)
        本次发送数据序列号为上次收到ack数据包的确认号
        本次确认号为上次收到数据的序列号+实际收到数据长度

4. TCP特点

    1.实现机制复杂
    2.占用资源开销大
    3.安全、可靠、可控
    4.面向连接传输方式

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

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

相关文章

2024年了! 为什么还在用串口服务器?

在数字化飞速发展的2024年&#xff0c;串口服务器这一看似古老的技术仍然在工业自动化、远程监控和数据通信等领域发挥着重要作用。本文将从串口服务器的定义、功能、优势和使用场景四个方面来探讨&#xff0c;为什么串口服务器在今天仍然被广泛使用。 1. 什么是串口服务器 串口…

基于51单片机的红外计数器-1602显示

一.硬件方案 本设计的主要原理为&#xff1a;红外发射管发射红外线&#xff0c;红外接收管接收红外线&#xff0c;并且接收管当有红外线照射的时候&#xff0c;电阻比较小&#xff0c;当无线外线照射的时候电阻比较大&#xff0c;这样就可以通过一个电压比较器和一个基准电压进…

线程池ThreadPoolExecutor使用指南

线程池ThreadPoolExecutor使用指南 &#x1f9d0;使用线程池的好处是什么&#xff1f; 统一管理&#xff0c;减少资源获取创建的开销&#xff0c;提高利用率。 &#x1f527;线程池的参数 ​ThreadPoolExecutor​ 3 个最重要的参数&#xff1a; ​corePoolSize​ : 任务队列…

Linux系统编程:基础IO

目录 1.C语言文件回顾 2.系统文件I/O 2.1 系统接口介绍 2.2 文件描述符fd 2.3 重定向 2.4 理解缓冲区 2.5 理解文件系统 1.C语言文件回顾 在学习系统文件的操作之前&#xff0c;还记得C语言是如何进行对文件的操作的吗&#xff1f;下面看C语言接口&…

浪潮信息打造业界首款50℃进液温度服务器 PUE逼近理论极限1.0!

在科技飞速发展的今天&#xff0c;浪潮信息以其前瞻性的技术创新思维&#xff0c;再次突破行业极限&#xff0c;推出业界首个支持50℃进液温度的浸没式液冷服务器NF5180G7。这一创新成果不仅展现了浪潮信息在液冷技术领域的深厚实力&#xff0c;更标志着服务器冷却技术的一次重…

【2024亲测无坑】在Centos.7虚拟机上安装Oracle 19C

目录 一、安装环境准备 1、linux虚拟机安装 2、虚拟机快照 3、空间检查&软件上传 二、Oracle软件安装 1.preinstall安装及其他配置准备 2.oracle安装 三、数据库实例的安装 1.netca——网络配置助手 2.dbca——数据库配置助手 四、ORACLE 19C 在linux centos 7上…

基于PPO的强化学习超级马里奥自动通关

目录 一、环境准备 二、训练思路 1.训练初期&#xff1a; 2.思路整理及改进&#xff1a; 思路一&#xff1a; 思路二&#xff1a; 思路三&#xff1a; 思路四&#xff1a; 3.训练效果&#xff1a; 三、结果分析 四、完整代码 训练代码&#xff1a; 测试代码&#…

MySQL 日志(二)

本篇将继续介绍MySQL日志的相关内容 目录 一、二进制日志 简介 注意事项 删除二进制日志 查看二进制日志 二进制日志的格式 二、服务器日志维护 一、二进制日志 简介 二进制日志中主要记录了MySQL的更改事件&#xff08;不包含SELECT和SHOW),例如&#xff1a;表的…

Base64编码的工作原理与实际应用

目录 前言 一、什么是Base64编码&#xff1f; 二、Base64编码的原理 三、Base64编码的应用场景 四、为什么要使用Base 64 五、Base64加密解密的实现 前言 当你需要将二进制数据转换为可传输和存储的文本格式时&#xff0c;Base64编码是一个常用的选择。在这篇博客中&#…

C++ 51 之 继承中的构造和析构

对象构造和析构的调用原则 继承中的构造和析构 子类对象在创建时会首先调用父类的构造函数父类构造函数执行完毕后&#xff0c;才会调用子类的构造函数当父类构造函数有参数时&#xff0c;需要在子类初始化列表(参数列表)中显示调用父类构造函数析构函数调用顺序和构造函数相…

可以用来制作硬模空心耳机壳的胶粘剂有哪些种类?

可以用来制作硬模空心耳机壳的胶粘剂有哪些种类&#xff1f; 制作耳机壳的胶粘剂有很多种类&#xff0c;常见的有环氧树脂胶水、UV树脂胶、快干胶、热熔胶等。 这些胶粘剂都有不同的特点和适用场景&#xff0c;可以根据自己的需求选择合适的类型。 例如&#xff1a; 环氧树脂…

Adobe设计替代软件精选列表

Adobe软件的替代列表&#xff0c;最初由 XdanielArt 收集&#xff0c;并由社区改进。您可以随意打开问题或拉出请求&#xff0c;或从数据中创建图像(以便于共享)。列表总是按照免费和开源选项的顺序排列&#xff0c;但根据您的用例&#xff0c;它可能不是最佳选择 替代因素 &am…

Python 潮流周刊#56:NumPy 2.0 里更快速的字符串函数

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景&#xff1a;帮助所有读者精进 Python 技术&am…

【linux】认识“文件”的本质,理解“文件系统”的设计逻辑,体会linux优雅的设计理念

⭐⭐⭐个人主页⭐⭐⭐ ~~~~~~~~~~~~~~~~~~ C站最❤❤❤萌❤❤❤博主 ~~~~~~~~~~~~~~~~~~~ ​♥东洛的克莱斯韦克-CSDN博客♥ ~~~~~~~~~~~~~~~~~~~~ 嗷呜~ ✌✌✌✌ 萌妹统治世界~ &#x1f389;&#x1f389;&#x1f389;&#x1f389; ✈✈✈✈相关文章✈✈✈✈ &#x1f4a…

2023年的Top20 AI应用在近一年表现怎么样?

AI应用现在进入寒武纪大爆发时代&#xff0c;百花争艳。如果倒回到2023年初&#xff0c;那时候排名靠前的AI应用在一年多时间&#xff0c;发生了哪些变化&#xff1f;能带给我们什么启示&#xff1f; 在2023年1月&#xff0c;排名靠前20的AI应用是&#xff1a; DeepL&#xff…

MATLAB中与直方图有关函数的关系

histogram Histogram plot画直方图 histcounts 直方图 bin 计数 histcounts是histogram的主要计算函数。 discretize 将数据划分为 bin 或类别 histogram2 画二元直方图 histcounts2 二元直方图 bin 计数 hist和histc过时了。替换不建议使用的 hist 和 histc 实例 hist → \r…

Day54 JDBC

Day54 JDBC JDBC&#xff1a;SUN公司提供的一套操作数据库的标准规范&#xff0c;就是使用Java语言操作关系型数据库的一套API JDBC与数据库驱动的关系&#xff1a;接口与实现的关系 给大家画一个jdbc的工作模式图 1.JDBC的四大金刚 1.DriverManager&#xff1a;用于注册驱动 2…

【Quartus 13.0】NIOS II 部署UART 和 PWM

打算在 EP1C3T144I7 芯片上部署 nios ii 做 uart & pwm控制 这个芯片或许不够做 QT 部署 这个芯片好老啊&#xff0c;但是做控制足够了&#xff0c;我只是想装13写 leader给的接口代码是用VHDL写的&#xff0c;我不会 当然verilog我也不太会 就这样&#xff0c;随便写吧 co…

SUSTAINABILITY,SCIESSCI双检期刊还能投吗?

本期&#xff0c;小编给大家介绍的是一本MDPI出版社旗下SCIE&SSCI双检“毕业神刊”——SUSTAINABILITY。据悉&#xff0c;早在2024年1月&#xff0c;ElSEVIER旗下的Scopus数据库已暂停收录检索期刊SUSTAINABILITY所发表文章&#xff0c;同时重新评估是否继续收录该期刊。随…

Qwen2——阿里巴巴最新的多语言模型挑战 Llama 3 等 SOTA

引言 经过几个月的期待&#xff0c; 阿里巴巴 Qwen 团队终于发布了 Qwen2 – 他们强大的语言模型系列的下一代发展。 Qwen2 代表了一次重大飞跃&#xff0c;拥有尖端的进步&#xff0c;有可能将其定位为 Meta 著名的最佳替代品 骆驼3 模型。在本次技术深入探讨中&#xff0c;我…