网络学了点socket,写个聊天室,还得改进

目录

第一版:

common

服务端:

客户端

第一版问题总结:

第二版

服务端:

客户端:

改进:

Windows客户端

一些小问题

还可以进行的改进


这篇文章我就先不讲网络基础的东西了,我讲讲在我进行制作我这个拉跨聊天室中遇到的问题,并写了三版代码.

第一版:

common

#pragma once
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>
#include <ctime>
#include <cstdarg>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "LockGuard.hpp"
enum
{
    SOCKET_ERROR = 1,
    BIND_ERROR,
    USAGE_ERROR
};

void Setserver(struct sockaddr_in &server,std::string &serverip,uint16_t &serverport)
{
    bzero(&server, sizeof(server));
    server.sin_port = htons(serverport);
    server.sin_addr.s_addr = inet_addr(serverip.c_str());
    server.sin_family=AF_INET;
}


class InetAddr
{
    void GetAddress(uint16_t *Port, std::string *Ip)
    {
        *Port = ntohs(_Addr.sin_port);
        *Ip = inet_ntoa(_Addr.sin_addr);
    }

public:
    InetAddr(struct sockaddr_in &Addr)
        : _Addr(Addr)
    {
        GetAddress(&_Port, &_Ip);
    }
    uint16_t Port()
    {
        return _Port;
    }
    std::string Ip()
    {
        return _Ip;
    }

private:
    struct sockaddr_in _Addr;
    uint16_t _Port;
    std::string _Ip;
};

服务端:

#pragma once
#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "log.hpp"
#include "Common.hpp"
const static int defaultfd = -1;

class Udpserver
{

public:
    Udpserver(uint16_t port)
        : _socketfd(defaultfd), _prot(port), _isrunning(false)
    {
    }
    void InitServer()
    {
        _socketfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_socketfd < 0)
        {
            LOG(WARNING, "%s", "sockfd创建失败");
        }
        LOG(INFO, "%s", "sock创建成功");
        // 填充sockaddr_in结构
        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;    // 设置家族协议
        local.sin_port = htons(_prot); // 设置端口号 换成网络序列
        // port要经过网络传输给对面,先到网络,_port:主机序列-> 主机序列,转成网络序列
        // a. 字符串风格的点分十进制的IP地址转成 4 字节IP
        // b. 主机序列,转成网络序列
        // in_addr_t inet_addr(const char *cp) -> 同时完成 a & b
        // local.sin_addr.s_addr = inet_addr(_ip.c_str()); // "192.168.3.1" -> 字符串风格的点分十进制的IP地址 -> 4字节IP
        local.sin_addr.s_addr = INADDR_ANY; // 随机ip地址 一般不能绑定确定ip地址

        // 开始绑定
        int n = bind(_socketfd, (struct sockaddr *)&local, sizeof(local));
        if (n < 0)
        {
            LOG(FATAL, "%s", "bind error");
            exit(BIND_ERROR);
        }
        LOG(INFO, "%s", "bind success");
    }

    void Start()
    {
        _isrunning = true;
        while (_isrunning)
        {
            char Inbuffer[1024];
            struct sockaddr_in peer;
            socklen_t socklen = sizeof(peer); // 初始化为sock
            // 让server收取数据 获取客户端socket
            ssize_t n = recvfrom(_socketfd, Inbuffer, sizeof(Inbuffer), 0, (struct sockaddr *)&peer,&socklen); // 接受
            if (n > 0)
            {
                std::cout <<"client say:";
                std::cout << Inbuffer << std::endl; // 成功就打印出来

                // sendto(_sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&peer, len);
                LOG(DEBUG, "建立 客户IP:%s 连接端口:%s", netAddr.Ip().c_str(), netAddr.Port());
                // sendto(_socketfd,buffer,sizeof(buffer),0,(struct sockaddr*)&sockaddr_in,socklen);//发送
            }
            //
            ///发/
            //
            InetAddr netAddr(peer);
            std::string message;
            std::cout << "server:";
            getline(std::cin, message);
            sendto(_socketfd, message.c_str(), message.size(), 0, (struct sockaddr *)&peer, socklen); // 发送
        }
        _isrunning = false;
    }

private:
    int _socketfd;
    uint16_t _prot;
    bool _isrunning;
};

客户端

#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "log.hpp"
#include "Common.hpp"

static bool isrunning = false;
static std::string Clientname;
void useagge(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        useagge(argv[0]);
        exit(USAGE_ERROR);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::atoi(argv[2]);
    std::cout << "你是?" << std::endl;
    std::cin >> Clientname;
    // 创建socket;
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        LOG(WARNING, "%s", "Sock错误创建失败");
    }
    LOG(INFO, "%s", "sock创建成功");
    isrunning = true;
    struct sockaddr_in server;
    Setserver(server, serverip, serverport);
    struct sockaddr_in local;
    bzero(&local, sizeof(local));
    std::cout << "可以进行通信了!" << std::endl;
    
    while (isrunning)
    {
      
        std::cout << "server:";
        std::string message;
        getline(std::cin, message);
        sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&server, socklen); // 发送
        
        struct sockaddr_in peer;
        socklen_t socklen = sizeof(peer); // 初始化为sock
        char buffer[1024];
        ssize_t n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &socklen);
        if (n > 0)
        {
            buffer[n] = 0;
            std::cout << "server: " << buffer << std::endl;
        }
    }
    return 0;
}

第一版问题总结:

我一开始是想着这个流程,因为一开始服务端只是接受客户端,服务端不会发消息给客户端,所以我想在原基础上,让两端都可以接受和发送,当时就有想可以多线程实行接受和发的任务,但是觉得上线程太麻烦就决定是服务端发->客户端收->客户端发->服务器收,这一条链路实行,但是问题是,我把收发是写在循环里,而 recvfrom是非阻塞等待的,所以双方实际上永远等不到对方信息

所以实际上仍然是要让多线程实行接受和发的任务

第二版

服务端:

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <thread>
#include <mutex>
#include "log.hpp"
#include "Common.hpp"
const static int defaultfd = -1;
 public:
    Udpserver(uint16_t port)
        : _socketfd(defaultfd), _prot(port), _isrunning(false)
    {
        _socklen = sizeof(_peer);
        InitServer();
    }
    void InitServer()
    {
        _socketfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_socketfd < 0)
        {
            LOG(WARNING, "%s", "sockfd创建失败");
        }
        LOG(INFO, "%s", "sock创建成功");
        // 填充sockaddr_in结构
        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;    // 设置家族协议
        local.sin_port = htons(_prot); // 设置端口号 换成网络序列
        // port要经过网络传输给对面,先到网络,_port:主机序列-> 主机序列,转成网络序列
        // a. 字符串风格的点分十进制的IP地址转成 4 字节IP
        // b. 主机序列,转成网络序列
        // in_addr_t inet_addr(const char *cp) -> 同时完成 a & b
        // local.sin_addr.s_addr = inet_addr(_ip.c_str()); // "192.168.3.1" -> 字符串风格的点分十进制的IP地址 -> 4字节IP
        local.sin_addr.s_addr = INADDR_ANY; // 随机ip地址 一般不能绑定确定ip地址

        // 开始绑定
        int n = bind(_socketfd, (struct sockaddr *)&local, sizeof(local));
        if (n < 0)
        {
            LOG(FATAL, "%s", "bind error");
            exit(BIND_ERROR);
        }
        LOG(INFO, "%s", "bind success");
        _isrunning = true;
    }

    void Start()
    void receive()
    {
        _isrunning = true;
        while (_isrunning)
        {
            
            char Inbuffer[1024] = {0}; // 初始化缓冲区
            struct sockaddr_in tempPeer;
            socklen_t tempSocklen = sizeof(tempPeer);
            ssize_t n = recvfrom(_socketfd, Inbuffer, sizeof(Inbuffer) - 1, 0, (struct sockaddr *)&tempPeer, &tempSocklen);
            if (n > 0)
            {
                std::cout <<"client say:";
                std::cout << Inbuffer << std::endl; // 成功就打印出来

                // sendto(_sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&peer, len);
                LOG(DEBUG, "建立 客户IP:%s 连接端口:%s", netAddr.Ip().c_str(), netAddr.Port());
                // sendto(_socketfd,buffer,sizeof(buffer),0,(struct sockaddr*)&sockaddr_in,socklen);//发送
                Inbuffer[n] = 0;
                std::lock_guard<std::mutex> lock(_peerMutex);
                _peer = tempPeer;
                _socklen = tempSocklen;
                std::cout << "client says:" << Inbuffer << std::endl;
            }
            //
            ///发/
            //
            InetAddr netAddr(peer);
            else
            {
                perror("recvfrom error");
            }
        }
    }
    void sent()
    {
        while (_isrunning)
        {
            std::string message;
            std::cout << "server: ";
            std::cin >> message;
            std::lock_guard<std::mutex> lock(_peerMutex);
            ssize_t sent = sendto(_socketfd, message.c_str(), message.size(), 0, (struct sockaddr *)&_peer, _socklen);
            if (sent == -1)
            {
                perror("sendto error");
            }
        }
        _isrunning = false;
    }
    void Start()
    {
        std::thread recvThread(&Udpserver::receive, this);
        std::thread sendThread(&Udpserver::sent, this);

        recvThread.detach();
        sendThread.detach();
        while (_isrunning)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
        close(_socketfd);
    }

private:
    int _socketfd;
    uint16_t _prot;
    bool _isrunning;
    //
    struct sockaddr_in _peer;
    socklen_t _socklen;

    std::mutex _peerMutex;
};

客户端:

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <memory>
#include <thread>
#include "log.hpp"
#include "Common.hpp"

static bool isrunning = false;
static std::string Clientname;

class Client
{
public:
    Client(const std::string &server_ip, uint16_t server_port)
    {
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd == -1)
        {
            perror("socket creation failed");
            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.c_str(), &_serverAddr.sin_addr) <= 0)
        {
            perror("inet_pton failed");
            close(_sockfd);
            exit(EXIT_FAILURE);
        }

        _isrunning = true;
    }
    void start()
    {
        std::cout << "你是? ";
        std::cin >> _clientName;
        std::cout << "可以进行通信了!" << std::endl;

        std::thread recvThread(&Client::receive, this);
        std::thread sendThread(&Client::send, this);

        recvThread.detach();
        sendThread.detach();

        while (_isrunning)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        close(_sockfd);
    }

private:
    void receive()
    {
        while (_isrunning)
        {
            char buffer[1024] = {0};
            struct sockaddr_in peer;
            socklen_t socklen = sizeof(peer);

            ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &socklen);
            if (n > 0)
            {
                buffer[n] = 0;
                std::cout << "server: " << buffer << std::endl;
            }
            else if (n == -1)
            {
                perror("recvfrom error");
            }
        }
    }
    void send()
    {
        while (_isrunning)
        {
            std::cout << _clientName << ": ";
            std::string message;
            std::cin >> message;

            ssize_t sent = sendto(_sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&_serverAddr, sizeof(_serverAddr));
            if (sent == -1)
            {
                perror("sendto error");
            }
        }
    }

private:
    int _sockfd;
    struct sockaddr_in _serverAddr;
    bool _isrunning;
    std::string _clientName;
};

改进:

这一版上,我添加了多线程和锁,能让客户端服务端进行并发的运行,并收发消息

Windows客户端

由于我想让Windows朋友也能与我建立通信,所以我在客户端上进行了修改成Windows版本

 #define  _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <thread>
#include <memory>

#pragma comment(lib, "Ws2_32.lib")

static bool isrunning = false;
static std::string Clientname;

class Client
{
public:
    Client(const std::string& server_ip, uint16_t server_port)
    {
        WSADATA wsaData;
        int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (result != 0)
        {
            std::cerr << "WSAStartup failed: " << result << std::endl;
            exit(EXIT_FAILURE);
        }

        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd == INVALID_SOCKET)
        {
            std::cerr << "socket creation failed: " << WSAGetLastError() << std::endl;
            WSACleanup();
            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.c_str(), &_serverAddr.sin_addr) <= 0)
        {
            std::cerr << "inet_pton failed: " << WSAGetLastError() << std::endl;
            closesocket(_sockfd);
            WSACleanup();
            exit(EXIT_FAILURE);
        }

        _isrunning = true;
    }

    void start()
    {
        std::cout << "你是? ";
        std::cin >> _clientName;
        std::cout << "可以进行通信了!" << std::endl;

        std::thread recvThread(&Client::receive, this);
        std::thread sendThread(&Client::send, this);

        recvThread.detach();
        sendThread.detach();

        while (_isrunning)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        closesocket(_sockfd);
        WSACleanup();
    }

private:
    void receive()
    {
        while (_isrunning)
        {
            char buffer[1024] = { 0 };
            struct sockaddr_in peer;
            int peerlen = sizeof(peer);

            int n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&peer, &peerlen);
            if (n > 0)
            {
                buffer[n] = 0;
                std::cout << "server: " << buffer << std::endl;
            }
            else if (n == SOCKET_ERROR)
            {
                std::cerr << "recvfrom error: " << WSAGetLastError() << std::endl;
            }
        }
    }

    void send()
    {
        while (_isrunning)
        {
            std::cout << _clientName << ": ";
            std::string message;
            std::cin >> message;

            int sent = sendto(_sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&_serverAddr, sizeof(_serverAddr));
            if (sent == SOCKET_ERROR)
            {
                std::cerr << "sendto error: " << WSAGetLastError() << std::endl;
            }
        }
    }

private:
    SOCKET _sockfd;
    struct sockaddr_in _serverAddr;
    bool _isrunning;
    std::string _clientName;
};

void useagge(const std::string& proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
        << std::endl;
}

int main()
{
    std::string serverip;
    std::string portStr;
    std::cout << "输入服务器ip: ";
    std::cin >> serverip;
    std::cout << "输入服务器端口号: ";
    std::cin >> portStr;

    uint16_t serverport;
    try
    {
        serverport = static_cast<uint16_t>(std::stoi(portStr));
    }
    catch (const std::exception& e)
    {
        std::cerr << "无效的端口号: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    std::unique_ptr<Client> csvr = std::make_unique<Client>(serverip, serverport); // C++14
    csvr->start();
    return 0;
}

一些小问题

由于我用的云服务器,大部分端口号是默认禁用的,所以端口号要自己进行开放,我用的阿里云,开放端口的地方在这里

还可以进行的改进

1.目前服务端和客户端仍然是1对1的关系,如果有第二个用户上线,就会挤占第一个用户,所以这里可以用一个vector来对用户的ip进行管理,来统一收所有用户消息

2.目前还没有将用户的名字传输给服务端,后续可以加上

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

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

相关文章

MyBatis映射器:实现动态SQL语句

大家好&#xff0c;我是王有志&#xff0c;一个分享硬核 Java 技术的金融摸鱼侠&#xff0c;欢迎大家加入 Java 人自己的交流群“共同富裕的 Java 人”。 上一篇文章中&#xff0c;我们已经学习了如何在 MyBatis 的映射器中通过简单的 SQL 语句实现增删改查&#xff0c;今天我…

关闭windows11磁盘地址栏上的历史记录

关闭windows11的磁盘地址栏上的历史记录 windows11打开磁盘后访问某一个磁盘路径后会记录这个磁盘路径&#xff0c;而且有时候会卡住这个地址栏&#xff08;关都关不掉&#xff09;&#xff0c;非常麻烦。 如下图所示&#xff1a; 关闭地址栏历史记录 按下windows键打开开…

C++面试八股文:static和const的关键字有哪些用法?

100编程书屋_孔夫子旧书网 某日二师兄参加XXX科技公司的C工程师开发岗位第7面&#xff1a; 面试官&#xff1a;C中&#xff0c;static和const的关键字有哪些用法? 二师兄&#xff1a;satic关键字主要用在以下三个方面&#xff1a;1.用在全局作用域&#xff0c;修饰的变量或者…

Adobe Premiere Pro 2024下载安装(视频剪辑软件Pr2024)

百度网盘下载地址&#xff08;含PR教学课程&#xff08;PR从入门到精通108节课程&#xff09;&#xff09;https://pan.baidu.com/s/1WKYZENoMzTcKhbgMgbEPGQ?pwdSIMS 一、Pr简介 Pr全称Premiere&#xff0c;是Adobe公司开发的一款功能强大的视频剪辑软件&#xff0c;目前被…

Java实现物候相机和植被分析导出相对指数成果图

一、基础概念 植被分析是利用地理信息系统&#xff08;GIS&#xff09;、遥感技术、生态学、环境科学等多学科交叉手段&#xff0c;对植被的分布、类型、结构、组成、动态变化、生产力、生态功能进行量化评估的过程。植被分析对于生态保护、生物多样性研究、资源管理、环境监测…

Mysql基础 - 事务

Mysql基础 - 事务 文章目录 Mysql基础 - 事务1 事务简介2 事务操作2.1 控制事务一2.2 控制事务二 3 事务四大特性4 并发事务问题5 事务隔离级别 1 事务简介 事务是一组操作的集合&#xff0c;他是一个不可分割的工作单位&#xff0c;事务会把所有操作作为一个整体一起向系统提…

[chisel]马上要火的硬件语言,快来了解一下优缺点

Chisel是什么&#xff1f; Chisel的全称为Constructing Hardware In a Scala Embedded Language&#xff0c;是一个基于Scala的DSL&#xff08;Domain Specific Language&#xff0c;特定领域专用语言&#xff09;。2012年&#xff0c;加州大学伯克利分校&#xff08;UC Berkel…

【Rd-03E】使用CH340给Rd03_E雷达模块烧录固件

Rd03_E 指导手册 安信可新品雷达模组Rd-03搭配STM32制作简易人体感应雷达灯教程 http://t.csdnimg.cn/mqhkE 测距指导手册网址&#xff1a; https://docs.ai-thinker.com/_media/rd-03e%E7%B2%BE%E5%87%86%E6%B5%8B%E8%B7%9D%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8C%E4%B8%AD%…

02-JAVA面向对象编程

一、面向对象编程 1、面向过程编程思想&#xff08;Process Oritented Programming&#xff09; 将实现一个功能的一组指令组合在一起&#xff0c;成为一个函数。这个函数就能实现这一个功能&#xff0c;是对功能实现的一种抽象。通过这种抽象方式&#xff0c;将代码实现复用。…

软件游戏steam_api.dll丢失的解决方法,总结5种有效的方法

在玩电脑游戏时&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“游戏缺少steam_api.dll”。这个问题可能让很多玩家感到困惑和烦恼。那么&#xff0c;究竟是什么原因导致游戏缺少steam_api.dll呢&#xff1f;又该如何解决这个问题呢&#xff1f;本文将为大家…

pyqt opengl 小黑块

目录 OpenGLWidget_g初始化函数&#xff1a; 解决方法&#xff1a;把初始化函数的parent去掉 pyqt opengl 小黑块 原因&#xff1a; 创建OpenGLWidget_g的时候把main_window作为父类&#xff08;self&#xff09;传进去了&#xff0c; self.opengl_widget OpenGLWidget_g(…

SpringBoot+Vue网上超市系统(前后端分离)

技术栈 JavaSpringBootMavenMySQLMyBatisVueShiroElement-UI 系统角色对应功能 用户管理员 系统功能截图

【云岚到家】-day02-2-客户管理-认证授权

【云岚到家】-day02-2-客户管理-认证授权 第二章 客户管理1 认证模块1.1 需求分析1.2 小程序认证1.2.1 测试小程序认证1.2.1.1 参考官方流程1.2.1.2 申请小程序账号1.2.1.3 创建jzo2o-customer1.2.1.4 部署前端1.2.1.5 编译运行1.2.1.6 真机调试 2 阅读代码2.1 小程序认证流程2…

定个小目标之刷LeetCode热题(15)

这道题直接就采用两数相加的规则&#xff0c;维护一个进阶值&#xff08;n&#xff09;即可&#xff0c;代码如下 class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {// 新建一个值为0的头结点ListNode newHead new ListNode(0);// 创建几个指针用于…

大数据解决方案案例:电商平台日志分析

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

PythonX.X、pipX的关系

PythonX.X、pipX的关系 Python2.x 与 3.x Python 的 3.0 版本&#xff0c;相对于 Python 的早期版本&#xff0c;是一个大的升级。许多针对早期 Python2.x 版本设计的程序都无法在 Python 3.x 上正常执行。为了照顾大量的历史遗留项目&#xff0c;Python 2.6 作为一个过渡版本…

Chat-TTS:windows本地部署实践【有手就行】

最近Chat-TTS模型很火&#xff0c;生成的语音以假乱真&#xff0c;几乎听不出AI的味道。我自己在本地部署玩了一下&#xff0c;记录一下其中遇到的问题。 环境&#xff1a; 系统&#xff1a;windows 11 GPU&#xff1a; Nvidia 4060 Cuda&#xff1a;12.1&#xff08;建议安…

数据结构与算法题目集(中文)6-2顺序表操作集

题目地址 https://pintia.cn/problem-sets/15/exam/problems/type/6?problemSetProblemId725&page0 注意审题&#xff0c;返回false的时候不要返回ERROR&#xff0c;否则答案错误&#xff0c;机器规则是死的。 位置一般指数组下标&#xff0c;位序一般指数组下标1。但是思…

error while loading shared libraries 找不到动态库问题如何解决

在使用 c 或 c 开发应用时&#xff0c;在启动程序时&#xff0c;有时会遇到这个错误&#xff0c;找不到动态库。这个时候&#xff0c;我们使用 ldd 来查看&#xff0c;发现可执行文件依赖的动态库显示为 not found。 1 实验代码 使用如下 3 个文件做实验。 hello.h 中声明了函…

学习DHCP动态主机配置协议

目录&#xff1a; dhcp 动态主机配置协议 ftp文件传输协议 dhcp 动态主机配置协议 服务器配置好了地址池 192.168.124.10 -192.168.124.20 客户端从地址池当中随机获取一个ip地址&#xff0c;ip地址会发生变化&#xff0c;使用服务端提供的ip地址&…