利用原始socket简单实现FTP的客户端和服务器端程序

2023-11-18

1.设计目的
本设计旨在利用原始socket简单实现FTP(File Transfer Protocol,文件传输协议)的客户端和服务器端程序,能够实现get、put、pwd、dir、cd等基本交互命令。

2.具体要求
用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),该程序应能实现下述命令功能:
get:取远方的一个文件
put:传给远方一个文件
pwd:显示远主当前目录
dir:列出远方当前目录
cd :改变远方当前目录
? :显示你提供的命令
quit :退出返回

3.程序实现
3.1 client.c(客户端代码实现)

#include "Winsock.h"
#include "windows.h" 
#include "stdio.h" 
#include "time.h" 
#include <iostream>
using namespace std;
#define RECV_PORT 3312 
#define SEND_PORT 4302  
#pragma comment(lib, "wsock32.lib")
SOCKET sockclient;
char filename[20];                       //文件名  
sockaddr_in ServerAddr;                 //服务器地址 
char rbuff[1024];                        //接收缓冲区  
char sbuff[1024];                       //发送缓冲区  
char InputIP[20];                       //存储输入的服务器IP


void help()//处理help
{
 cout << "                         欢迎进入迷你FTP帮助菜单              " << endl
<< "                  * * * * * * * * * * * * * * * * * * * * *       " << endl
<< "                  1.get....................下载(接受)文件      " << endl
<< "                     get的用法: get 文件名                         " << endl << endl
<< "                  2.put.................上传(发送)文件       " << endl
<< "                     put的用法:put 文件名                         " << endl
<< "                  3.pwd..........显示当前文件夹的绝对路径       " << endl
<< "                  4.dir............显示远方当前目录的文件       " << endl << endl
<< "                  5.cd.............改变远方当前目录和路径       " << endl
<< "                   cd的用法(进入下级目录): cd 路径名             " << endl
<< "                   cd的用法(进入上级目录): cd ..                 " << endl << endl
<< "                  6.?或者help................进入帮助菜单      " << endl
<< "                  7.quit..........................退出FTP       " << endl
<< "                  * * * * * * * * * * * * * * * * * * * * *       " << endl;

void list(SOCKET sockfd)
{
    int nRead;
    while (true)
    {
        nRead = recv(sockclient, rbuff, 1024, 0);
        //recv函数通过sockclient套接口接受数据存入rbuff缓冲区,返回接受到的字节数      
        if (nRead == SOCKET_ERROR)
        {
            printf("read response error!\n");
            exit(1);
        }
        if (nRead == 0)//数据读取结束        
            break;
        //显示数据   
        rbuff[nRead] = '\0';
        printf("%s", rbuff);
    }
}

/*********************** put:传给远方一个文件***************************/
int SendFile(SOCKET datatcps, FILE* file)
{
    printf(" sending file data..");
    for (;;)  //从文件中循环读取数据并发送客户端       
    {
        int r = fread(sbuff, 1, 1024, file);//fread函数从file文件读取1个1024长度的数据到sbuff,返回成功读取的元素个数            
        if (send(datatcps, sbuff, r, 0) == SOCKET_ERROR)
        {
            printf("lost the connection to client!\n");
            closesocket(datatcps);
            return 0;
        }
        if (r<1024)                      //文件传送结束    
            break;
    }
    closesocket(datatcps);
    printf("done\n");
    return 1;
}


DWORD StartSock()//启动winsock 
{
    WSADATA WSAData;
    char a[20];
    memset(a, 0, 20);
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)//加载winsock版本
    {
        printf("sock init fail!\n");
        return (-1);
    }
    if (strncmp(InputIP, a, 20) == 0)
    {
        printf("请输入连接的主机IP:");
        scanf("%s", &InputIP);
    }
    //设置地址结构
    ServerAddr.sin_family = AF_INET;//AF_INET表示使用IP地址族 
    ServerAddr.sin_addr.s_addr = inet_addr(InputIP);//指定服务器IP 
    ServerAddr.sin_port = htons(RECV_PORT);//设置端口号 
    return(1);
}


//创建套接字  
DWORD CreateSocket()
{
    sockclient = socket(AF_INET, SOCK_STREAM, 0);//当socket函数成功调用时返回一个新的SOCKET(Socket Descriptor) 
    if (sockclient == SOCKET_ERROR)
    {
        printf("sockclient create fail! \n");
        WSACleanup();
        return(-1);
    }
    return(1);
}
DWORD CallServer() //发送连接请求  
{
    CreateSocket();

    if (connect(sockclient, (struct  sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)  
    {//connect函数创建与指定外部端口的连接
        printf("Connect fail \n");
        memset(InputIP, 0, 20);
        return(-1);
    }
    return(1);
}

DWORD TCPSend(char data[])   //发送命令  
{
    int length;
    length = send(sockclient, data, strlen(data), 0);
    //send函数通过sockclient接口发送data里面的数据,发送成功返回发送的字节数  
    if (length <= 0)
    {
        printf("send data error ! \n");
        closesocket(sockclient);
        WSACleanup();
        return(-1);
    }
    return(1);
}


int main()
{
    char messge1[10];           //定义输入要处理的文件名  
    char messge2[20];           //定义输入要处理的文件名 
    char order[30];             //输入的命令    
    order[0] = '\0';
    char buff[80];              //用以存储经过字串格式化的order  
    FILE *fd;                   //File协议主要用于访问本地计算机中的文件,fd指针指向要访问的目标文件  
    FILE *fd2;
    int count;
    int sin_size = sizeof(ServerAddr);
    StartSock();
    if (CallServer() == -1)
        return main();          //发送连接请求失败,返回主函数  
    printf("\n请输入命令(输入?或help进入帮助菜单):\n");
    memset(buff, 0, 80);            //清空数组   
    memset(messge2, 0, 20);
    memset(order, 0, 30);
    memset(messge1, 0, 10);
    memset(rbuff, 0, 1024);
    memset(sbuff, 0, 1024);
    scanf("%s", &messge1);//s%输入字符串
    if (strncmp(messge1, "get", 3) == 0)
        scanf("%s", &messge2);
    if (strncmp(messge1, "put", 3) == 0)
        scanf("%s", &messge2);
    if (strncmp(messge1, "cd", 2) == 0)
        scanf("%s", &messge2);
    strcat(order, messge1);         //把messge1加在order的末尾   
    strcat(order, " ");             //命令中间的空格    
    strcat(order, messge2);         //把messge2加在order的末尾     
    sprintf(buff, order);           //把调整格式的order存入buff

    //help和?    
    if (strncmp(messge1, "help", 4) == 0) {
        help();
    }
    if (strncmp(messge1, "?", 1) == 0){
        help();
    }

    if (strncmp(messge1, "quit", 4) == 0)
    {
        printf("                    欢迎再次进入迷你FTP,谢谢使用!\n");
        closesocket(sockclient);
        WSACleanup();
        return 0;
    }
    TCPSend(buff);//发送buff里面的数据        
    recv(sockclient, rbuff, 1024, 0);
    printf(rbuff);

    if (strncmp(rbuff, "get", 3) == 0)      //get
    {
        fd = fopen(messge2, "wb");//使用二进制方式,打开文件,wb只写打开或新 建一个二进制文件;只允许写数据。              
        if (fd == NULL)
        {
            printf("open file %s for weite failed!\n", messge2);
            return 0;
        }
        while ((count = recv(sockclient, rbuff, 1024, 0))>0)
        {
            fwrite(rbuff, sizeof(rbuff), count, fd);
        }
        //把count个数据长度为size0f()的数据从 rbuff输入到fd指向的目标文件             
        fclose(fd);        //关闭文件    
    }

    if (strncmp(rbuff, "put", 3) == 0)   //put 
    {
        strcpy(filename, rbuff + 9);
        fd2 = fopen(filename, "rb");//rb读写打开一个二进制文件,只允许读写数据。 
        if (fd2)
        {
            if (!SendFile(sockclient, fd2)){
                printf("send failed!");
                return 0;
            }
            fclose(fd2);
        }//关闭文件 

        else//打开文件失败  
        {
            strcpy(sbuff, "can't open file!\n");
            if (send(sockclient, sbuff, 1024, 0))
                return 0;
        }
    }

    if (strncmp(rbuff, "dir", 3) == 0)      //dir 
    {
        printf("\n");
        list(sockclient);               //列出接受到的列表内容
    }
    if (strncmp(rbuff, "pwd", 3) == 0)
    {
        list(sockclient);               //列出接受到的内容--绝对路径
    }
    if (strncmp(rbuff, "cd", 2) == 0){}      //cd 

    closesocket(sockclient);            //关闭连接
    WSACleanup();                       //释放Winsock    
    return main();
}

3.2 server.c(服务端代码实现)

#include "Winsock.h" 
#include "windows.h" 
#include "stdio.h"  
#define RECV_PORT 3312  
#define SEND_PORT 4302  
#pragma   comment(lib, "wsock32.lib")
SOCKET sockclient, sockserver;
 struct sockaddr_in ServerAddr;//服务器地址
 struct sockaddr_in ClientAddr;//客户端地址 

/***********************全局变量***********************/
int Addrlen;//地址长度 
char filename[20];//文件名 
char order[10];//命令  
char rbuff[1024];//接收缓冲区  
char sbuff[1024];//发送缓冲区  


DWORD StartSock()    //初始化winsock   
{
    WSADATA WSAData;
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
    {
        printf("socket init fail!\n");
        return (-1);
    }
    return(1);
}

DWORD CreateSocket()
{
    sockclient = socket(AF_INET, SOCK_STREAM, 0);
    if (sockclient == SOCKET_ERROR)
    {
        printf("sockclient create fail ! \n");
        WSACleanup();
        return(-1);
    }
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    ServerAddr.sin_port = htons(RECV_PORT);
    if (bind(sockclient, (struct  sockaddr  FAR  *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
    {                     //bind函数将套接字和地址结构绑定   
        printf("bind is the error");
        return(-1);
    }
    return (1);
}

int SendFileRecord(SOCKET datatcps, WIN32_FIND_DATA *pfd)     //用来发送当前文件记录 
{
    char filerecord[MAX_PATH + 32];
    FILETIME ft;         //文件建立时间   
    FileTimeToLocalFileTime(&pfd->ftLastWriteTime, &ft);
    SYSTEMTIME lastwtime;     //SYSTEMTIME系统时间数据结构   
    FileTimeToSystemTime(&ft, &lastwtime);
    char *dir = pfd->dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY ? "<DIR>" : " ";
    sprintf(filerecord, "%04d-%02d-%02d %02d:%02d  %5s %10d   %-20s\n",
        lastwtime.wYear,
        lastwtime.wMonth,
        lastwtime.wDay,
        lastwtime.wHour,
        lastwtime.wMinute,
        dir,
        pfd->nFileSizeLow,
        pfd->cFileName);
    if (send(datatcps, filerecord, strlen(filerecord), 0) == SOCKET_ERROR)
    { //通过datatcps接口发送filerecord数据,成功返回发送的字节数   
        printf("Error occurs when sending file list!\n");
        return 0;
    }
    return 1;
}

int SendFileList(SOCKET datatcps)
{
    HANDLE hff;//建立一个线程  
    WIN32_FIND_DATA fd;   //搜索文件   
//可以通过FindFirstFile()函数根据当前的文件存放路径查找该文件来把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去  
    if (hff == INVALID_HANDLE_VALUE)//发生错误  
    {
        const char *errstr = "can't list files!\n";
        printf("list file error!\n");
        if (send(datatcps, errstr, strlen(errstr), 0) == SOCKET_ERROR)
        {
            printf("error occurs when senging file list!\n");
        }
        closesocket(datatcps);
        return 0;
    }

    BOOL fMoreFiles = TRUE;
    while (fMoreFiles)
    {//发送此项文件信息   
        if (!SendFileRecord(datatcps, &fd))
        {
            closesocket(datatcps);
            return 0;
        }
        //搜索下一个文件    
        fMoreFiles = FindNextFile(hff, &fd);
    }
    closesocket(datatcps);
    return 1;
}

int SendFile(SOCKET datatcps, FILE* file)
{
    printf(" sending file data..");
    for (;;)   //从文件中循环读取数据并发送客户端   
    {
        int r = fread(sbuff, 1, 1024, file);//把file里面的内容读到sbuff缓冲区   
        if (send(datatcps, sbuff, r, 0) == SOCKET_ERROR)
        {
            printf("lost the connection to client!\n");
            closesocket(datatcps);
            return 0;
        }
        if (r<1024)//文件传送结束    
            break;
    }
    closesocket(datatcps);
    printf("done\n");
    return 1;
}

//连接  
DWORD ConnectProcess()
{
    Addrlen = sizeof(ClientAddr);
    if (listen(sockclient, 5)<0)
    {
        printf("Listen error");
        return(-1);
    }
    printf("服务器监听中...\n");
    for (;;)
    {
        sockserver = accept(sockclient, (struct sockaddr FAR *)&ClientAddr, &Addrlen);
        //accept函数取出连接队列的第一个连接请求,sockclient是处于监听的套接字ClientAddr 是监听的对象地址,         
        //Addrlen是对象地址的长度 
        for (;;)
        {
            memset(rbuff, 0, 1024);
            memset(sbuff, 0, 1024);
            if (recv(sockserver, rbuff, 1024, 0) <= 0)
            {
                break;
            }
            printf("\n");
            printf("获取并执行的命令为:");
            printf(rbuff);
            if (strncmp(rbuff, "get", 3) == 0)
            {
                strcpy(filename, rbuff + 4); printf(filename);
                FILE *file; //定义一个文件访问指针    
                //处理下载文件请求    
                file = fopen(filename, "rb");//打开下载的文件,只允许读写   
                if (file)
                {
                    sprintf(sbuff, "get file %s\n", filename);
                    if (!send(sockserver, sbuff, 1024, 0))
                    {
                        fclose(file);      return 0;
                    }
                    else
                    {//创建额外数据连接传送数据     
                        if (!SendFile(sockserver, file))
                            return 0;
                        fclose(file);
                    }
                }//file   

                else//打开文件失败    
                {
                    strcpy(sbuff, "can't open file!\n");
                    if (send(sockserver, sbuff, 1024, 0))
                        return 0;
                } //lost 
            }//get

            if (strncmp(rbuff, "put", 3) == 0)
            {
                FILE *fd;
                int count;
                strcpy(filename, rbuff + 4);
                fd = fopen(filename, "wb");
                if (fd == NULL)
                {
                    printf("open file %s for weite failed!\n", filename);
                    return 0;
                }
                sprintf(sbuff, "put file %s", filename);
                if (!send(sockserver, sbuff, 1024, 0))
                {
                    fclose(fd);
                    return 0;
                }
                while ((count = recv(sockserver, rbuff, 1024, 0))>0)//recv函数返回接受的字节数赋给count          
                    fwrite(rbuff, sizeof(char), count, fd);
                //把count个数据长度为size0f()的数据从rbuff输入到fd指向的目标文件
                printf(" get %s succed!\n", filename);
                fclose(fd);
            }//put 

            if (strncmp(rbuff, "pwd", 3) == 0){
                char   path[1000];
                GetCurrentDirectory(1000, path);//找到当前进程的当前目录  
                strcpy(sbuff, path);
                send(sockserver, sbuff, 1024, 0);
            }//pwd   

            if (strncmp(rbuff, "dir", 3) == 0){
                strcpy(sbuff, rbuff);
                send(sockserver, sbuff, 1024, 0);
                SendFileList(sockserver);//发送当前列表 
            }//dir 

            if (strncmp(rbuff, "cd", 2) == 0)
            {
                strcpy(filename, rbuff + 3);
                strcpy(sbuff, rbuff);
                send(sockserver, sbuff, 1024, 0);
                SetCurrentDirectory(filename);//设置当前目录 
            }//cd  
            closesocket(sockserver);
        }//for 2
    }//for 1 
}


int main()
{
    if (StartSock() == -1)
        return(-1);
    if (CreateSocket() == -1)
        return(-1);
    if (ConnectProcess() == -1)
        return(-1);
    return(1);
}

4.简单的演示效果如下图:
先输入自己电脑的IP地址,然后回车就可以进入到主界面了

这里写图片描述

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用原始socket简单实现FTP的客户端和服务器端程序 的相关文章

  • IP地址、子网掩码、默认网关和DNS服务器之间的联系与区别

    文章目录 1 IP地址 2 子网掩码 3 默认网关 4 DNS服务器 1 IP地址 IP 是32位二进制数据 通常以十进制表示 并以 分隔 IP 地址是一种逻辑地址 用来标识网络中一个个主机 IP 有唯一性 指的是公网地址 即每台机器的 I
  • 计算机网络(五)——应用层HTTP协议

    HTTP 文章目录 HTTP 1 HTTP协议是什么 2 HTTP协议格式 2 1请求包含信息 2 2响应包含信息 2 3请求响应格式 2 4模拟发送请求打印响应结果 2 5请求响应头中的Content 2 6模拟响应服务器 3 HTTP优
  • IP数据报的发送和转发过程

    IP数据报的发送和转发过程 源主机如何知道目的主机是否与自己在同一网络中 同一个网络中的主机可以直接通信 这属于直接交付 不同网络中的主机不能直接通信 需要路由器的中转 这属于间接交付 现假设主机C给主机F发送ip数据报 主机C将自己的IP
  • 网络基础知识

    网络编程 2 网络的体系结构 七层模型 四层模型 因为网络通信比较麻烦 所以网络采用分层思想 OSI开放系统互联网模型 七层模型 高层 应用层 表示层 会话层 低层 传输层 网络层 数据链路层 物理层 驱动 网卡 仅仅是一种理想状态 现实中
  • IP组播 —— IP组播的概念和地址

    一 IP数据报的三种传输方式 二 IP组播地址的范围及特点 三 硬件组播
  • 现阶段计算机网络技术专业人才培养的发展对策

    确立具有高职特色的人才培养目标 在市场经济的条件下 人才培养首先要适应市场需求 以市场行业的需求为导 向制定人才培养目标 学校人才培养是否能满足社会需求 可以通过学生在对口行 业及相关领域的就业情况来衡量 高职教育培养高技能应用型人才 与研
  • 计算机网络 网络层——IP数据报 详记

    IP 数据报的格式 一个 IP 数据报由首部和数据两部分组成 首部的前一部分是固定长度 共 20 字节 是所有 IP 数据报必须具有的 在首部的固定部分的后面是一些可选字段 其长度是可变的 IP数据报首部的固定部分中的各字段 版本 占4位
  • 计算机网络重点知识(期末考研复习)

    点个关注 更多精彩持续更新为考研和期末助力 一起加油 计算机网络 第一章 思维导图 概述 计算机网络的主要性能指标 计算机网络的体系结构 OSI RM模型 TCP IP 两种模型对比 第二章 思维导图 数据通信主要指标与信道极限容量 多路通
  • 【常识系列】Java程序员需要了解的网络常识之计算机网络性能指标

    作为一个Java程序员 我们也需要对计算机的网络知识有一定的了解 本系列就是针对非运维小伙伴的网络常识介绍 不费脑子可以无聊的时候瞅一瞅 希望可以帮助到大家 计算机网络性能指标 速率 计算机发送的信号是以 二进制数字 形式的 一个二进制数字
  • 计算机网络 | 物理层下 传输媒介、信道复用技术,带宽接入技术

    文章目录 3 物理层下面的传输媒介 3 1 导引型传输媒介 3 2 非导引型传输媒介 4 信道复用技术 5 数字传输系统 5 1 旧的数字系统 5 2 新数字系统 6 带宽接入技
  • 计算机网络(二)| 物理层上 | 数据通信基础知识 调制 频率范围 信噪比

    文章目录 1 物理层基本概念 2 数据通信基础知识 2 1 数据通信基本概念 2 2 信道基本概念 2 2 1 基带调制 编码 方式 2 2 2 带通调制方式 2 3 信道的极
  • 期末备考 |《计算机网络》期末备考资料包来啦!

    写在前面 不知不觉又到了学期的末尾 不知道各位计算机er的 专业课复习得怎么样了呢 为了帮助大家更好地 备战期末 从今天开始 岛主将持续为大家更新 计算机期末备考资料 为同学们的绩点护航 今天岛主为大家带来的是 计算机网络 期末备考资料包
  • 计算机网络---vlan、单臂路由、静态路由综合案例配置(命令版)

    基础命令 1 检查设备是否连通 ping lt 目标主机 gt 例 ping 192 168 1 1 拓展 ping t lt 目标主机 gt 将不断发送ping请求 直至手动中断该命令 ctrl c ping c 4 lt 目标主机 gt
  • 计算机网络基础——常用的中英文网络述语大全,强烈建议收藏

    系统网络体系结构 System Network Architecture SNA 国际标准化组织 International Organization for Standardization ISO 开放系统互连基本参考模型 Open Sy
  • 计算机网络基础知识——OSI七层模型

    OSI 七层模型是计算机网络体系结构中的一个重要概念 它由七个层次组成 每一层都有其特定的功能和作用 这个模型最初是由 ISO 国际标准化组织 提出的 用于描述计算机网络中不同层次之间的交互方式 虽然 OSI 模型是一个理论模型 但是在实际
  • 计算机网络基础——光模块(Optical Modules)基础知识介绍

    一 光模块的工作原理 光模块 Optical Modules 的工作原理是将电信号转换为光信号 或者将光信号转换为电信号 实现光纤通信中的光电转换和电光转换功能 具体来说 光模块主要由光电子器件 光发射器和光接收器 功能电路和光接口等部分组
  • 计算机网络基础知识——OSI七层模型

    OSI 七层模型是计算机网络体系结构中的一个重要概念 它由七个层次组成 每一层都有其特定的功能和作用 这个模型最初是由 ISO 国际标准化组织 提出的 用于描述计算机网络中不同层次之间的交互方式 虽然 OSI 模型是一个理论模型 但是在实际
  • 计算机网络基础 走入计算机行业的重中之重

    计算机网络是指将地理位置不同的 功能独立的多台计算机通过通信线路连接起来 以功能完善的网络软件支撑 实现资源共享和信息传递的系统 对于信息安全高级工程师来说 理解计算机网络的基本原理是至关重要的 下面我们将逐一解析计算机网络的核心概念 网络
  • 计算机网络 网络层下 | IPv6 路由选择协议,P多播,虚拟专用网络VPN,MPLS多协议标签

    文章目录 5 IPv6 5 1 组成 5 2 IPv6地址 5 3 从IPv4向IPv6过渡 5 3 1 双协议栈 5 3 2 隧道技术 6 因特网的
  • 2023 全球网络黑客常用攻击方法 Top10_top10攻击

    近几年 借助互联网产业发展的东风 网络黑产也迎来更加巅峰的状态 不论是从攻击效率 组织规模 亦或是收益变现能力 都在一天天变的成熟完善 根据艾瑞咨询 2020 年发布的 现代网络诈骗分析报告 全国黑产从业者已经超过 40 万人 依托其从事网

随机推荐

  • MySQL简述1

    MySQL是什么 MySQL优点 MySQL的四种分类 数据库的三大范式 多表查询 左连接 右连接 内连接 交叉连接 显式 隐式 子查询 事物 特性 原子性 一致性 隔离性 持久性 并发问题 脏读 读未提交 不可重复读 读已提交 幻读 可重
  • 机器学习之高斯过程

    高斯过程 高斯过程 Gaussian Process 高斯分布 置信区间 随机过程 高斯分布的特点 核函数 白噪声处理 实战 高斯过程 Gaussian Process 在机器学习领域里 高斯过程是一种假设训练数据来自无限空间 并且各特征都
  • Fiddler 微信小程序抓图教程(非常详细)从零基础入门到精通,看完这一篇就够了

    前言 本篇文章主要给大家详细讲解如何用Fiddler爬取微信小程序的图片 内容图文并茂 流程非常简单 我们开始吧 目录 一 获取软件并打开 二 点击工具设置相关代理 三 如何抓图 四 答疑 五 总结 一 获取软件并打开 1 通过百度网盘下载
  • 因果推断----do演算

    do演算 合法 的do表达式变换 规则1 如果我们观察到变量W与Y无关 其前提可能是以其他变量Z为条件 那么Y的概率分布就不会随W而改变 即 P Y d
  • vue3+elementPlus-浏览器告警解决error.ts:14 ElementPlusError: [ElPagination] 你使用了一些已被废弃的用法,请参考 el-pagination

    问题 在使用elementuiPlus的分页器组件的时候 发现会有如下图警告 检查代码
  • 微信小程序父组件向子组件传参,子组件样式无效问题处理

    微信小程序父组件向子组件传参 子组件样式无效问题处理 父组件代码 引入 json usingComponents evaluate evaluate evaluate wxml
  • dp 1.4协议_浅析关于HDMI接口与DP接口

    显示器现在主流已经为HDMI接口与DP接口 那么这些接口都有什么区别 以下表格会大致做个区分 建议优先使用DP接口 HDMI2 1接口目前仅发布协议 尚未大规模商用在高清电视机上有部分应用 Mini DP接口版本为DP1 2 HDMI2 1
  • libcurl库安装心得

    一 libcurl简介 libcurl是一个跨平台的网络协议库 支持http https ftp gopher telnet dict file 和ldap 协议 libcurl同样支持HTTPS证书授权 HTTP POST HTTP PU
  • JSON工具类

    在实际开发中通服都是使用JSON格式数据 那么如何跟JSON打交道呢 下面就写一些JSON的常用转换工具 以及JSON数据提取 目录 阿里的FastJSON JSONObject类 JSON类 JSONArray JSONPath Json
  • 分子对接教程

    TCGA GEO 文献阅读 数据库 理论知识 R语言 Bioconductor 服务器与Linux 接前文 分子对接教程 1 软件安装准备 分子对接教程 2 选择合适的蛋白受体 分子对接教程 3 配体分子文件格式转换 分子对接教程 4 蛋白
  • QT 中文版信息提示框

    引言 在QT设计UI程序过程中 整套系统都是中文版本 然而信息提示默认只有中文 难免有点小纠结 这里针对QMessageBox稍微做了一点点改进 使其支持完美的中文提示框 调用方式非常简单 只需要将QMessageBox调用地方 改为QSh
  • 专家PID

    专家PID 专家控制 专家控制是模拟人类专家控制的方式 它具有大量的专门知识和经验 和专家控制一样不需要知道对象的模型的情况下 对系统进行控制 专家控制的基本结构 和人类专家控制一样 知识库越是丰富 推理机越是精确 控制效果也就越好 不同的
  • 数据结构C++ 栈Stack求值算法

    来自邓俊辉老师的数据结构 C 版 第95页 readNumber函数 可读整数和小数 注意 下列代码是直接用C 内部写好的stack实现的 而不是书中给出的stack模板 发现更简洁的readNumber函数 float readNumbe
  • 使用Vue解决跨域问题

    如果你是一个Web前端工程师 那么跨域这个问题肯定是绕不开的 1 创建 vue config js 设置 devServer 属性 module exports devServer webpack dev server配置 host loc
  • ECS共享型s6和ECS突发性能型t6的区别选择哪个好?

    WP建站 一个专注于wordpress学习的 关注他 2 人赞同了该文章 这两个类型的阿里云ecs服务器的话 一般在这两个中二选一的话我们建议优先选择ECS共享型s6 我们简单的来说说他们的一些区别和特点吧 首先我们要知道的是他们都是独立的
  • 线性代数-----行列式的性质

    行列式的性质 设 D a 11
  • cosmos测试网络结点搭建完整流程

    第一步 下载golang并安装 配置环境变量 wget https dl google com go go1 13 8 linux amd64 tar gz tar C usr local xzf go VERSION OS ARCH ta
  • CSDN周赛66期图文题解 - 路灯亮度 & 池塘水量

    本期非编程题考察更多是对原书的阅读理解 可能还是因为自己理解不够 翻了半天书 还是错了两道 失之我命 不多废话 本期编程题比较符合我的胃口 有陷阱 有技巧 窃以为是最近不少期里比较有意思的中等难度的题目了 美中不足的是两道题都没有给出数据范
  • 读写权限详解

    本篇博客主要通过三个问题来理清C C 中的读写权限问题 const变量可以赋值给非const引用吗 const变量的地址可以赋值给非const指针吗 const普通变量可以给非const普通变量赋值吗 在此之前 我们得先明白读写权限的一个基
  • 利用原始socket简单实现FTP的客户端和服务器端程序

    1 设计目的 本设计旨在利用原始socket简单实现FTP File Transfer Protocol 文件传输协议 的客户端和服务器端程序 能够实现get put pwd dir cd等基本交互命令 2 具体要求 用socket 编程接