`
shake863
  • 浏览: 661212 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux下rpc应用 例程详解

阅读更多

关于“RPC语言”
RPC语言也是一种专门的编程语言,当然这里我们不需要知道太多,只需要能看懂下面这种基本结构就行了:

program TESTPROG {
   version VERSION {
     string TEST(string) = 1;
   } = 1;
} = 87654321;

这里TESTPROG和VERSION是两个变量,用于标识一个单独的RPC接口。这被RPC服务程序,比如portmap用到,我们可以不用关心,变量名字也是随便取的。但取值要在你的系统中是唯一的。
“string TEST(string) = 1;”这一行说明有两个函数test_VERSION和test_VERSION_svc,这里由于VERSION变量为1,所以函数名为test_1和 test_1_svc,这两个函数用于在服务器端和客户端实现调用,即:
在客户端调用test_1函数,服务器端调用test_1_svc函数处理并返回。
函数的类型是string,RPC语言中string即C里面的一个字符串。所以上述函数有一个字符串作为参数传递,同时要返回字符串。即:
char ** test_1(char **argp, CLIENT *clnt) 和 char **test_1_svc(char **argp, struct svc_req *rqstp)

同理,如果声明是这样的:

program RDICTPROG  /* name of remote program ( not used ) */
{
    version RDICTVERS  /* declaration of version ( see below ) */
    {
        int INITW ( void )     = 1;  /* first procedure in this program */
        int INSERTW ( string ) = 2;  /* second procedure in this program */
        int DELETEW ( string ) = 3;  /* third procedure in this program */
        int LOOKUPW ( string ) = 4;  /* fourth procedure in this program */
    } = 1;  /* definition of the program version */
} = 0x30090949;  /* remote program number ( must be unique ) */

则 说明这个RPC中有四个函数可用,即客户端可以调用initw_1、insertw_1、deletew_1、lookupw_1四个函数来向服务端发送 消息,服务端可以用initw_1_svc、insertw_1_svc、deletew_1_svc、lookupw_1_svc四个函数来处理请求并 返回结果。

原任务
假设现在有这样一个程序,源代码如下:

/* dict.c -- main, initw, nextin, insertw, deletew, lookupw */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXWORD 50        /* maximum length of a command or word */
#define DICTSIZ 100        /* maximum number of entries in dictionary. */
char dict[DICTSIZ][MAXWORD + 1];    /* storage for a dictionary of words */
int nwords = 0;            /* number of words in the dictionary */
/* 函数原型 */
int nextin(char *cmd, char *word);
int initw(void);
int insertw(const char *word);
int deletew(const char *word);
int lookupw(const char *word);
/* ------------------------------------------------------------------
* main -- insert, delete, or lookup words in a dictionary as specified
* ------------------------------------------------------------------ */
int main(int argc, char *argv[])
{
    char word[MAXWORD + 1];    /* space to hold word from input line */
    char cmd;
    int wordlen;        /* length of input word */
    printf("Please input:\n");
    while (1) {
    wordlen = nextin(&cmd, word);
    if (wordlen < 0) {
        exit(0);
    }
    switch (cmd) {
    case 'I':        /* 初始化 */
        initw();
        printf("Dictionary initialized to empty.\n");
        break;
    case 'i':        /* 插入 */
        insertw(word);
        printf("%s inserted.\n", word);
        break;
    case 'd':        /* 删除 */
        if (deletew(word)) {
        printf("%s deleted.\n", word);
        } else {
        printf("%s not found.\n", word);
        }
        break;
    case 'l':        /* 查询 */
        if (lookupw(word)) {
        printf("%s was found.\n", word);
        } else {
        printf("%s was not found.\n", word);
        }
        break;
    case 'q':        /* 退出 */
        printf("Program quits.\n");
        exit(0);
        break;
    default:        /* 非法输入 */
        printf("command %c invalid.\n", cmd);
        break;
    }            /* end of switch */
    }                /* end of while */
    return 0;
}                /* end of main */

/* ------------------------------------------------------------------
* nextin -- read a command and(possibly) a word from the next input line
* ------------------------------------------------------------------ */
int nextin(char *cmd, char *word)
{
    int i, ch;
    ch = getc(stdin);
    while (isspace(ch)) {
    ch = getc(stdin);
    }                /* end of while */
    if (ch == EOF) {
    return (-1);
    }
    *cmd = (char) ch;
    ch = getc(stdin);
    while (isspace(ch)) {
    ch = getc(stdin);
    }                /* end of while */
    if (ch == EOF) {
    return (-1);
    }
    if (ch == '\n') {
    return (0);
    }
    i = 0;
    while (!isspace(ch)) {
    if (++i > MAXWORD) {
        printf("error: word too long.\n");
        exit(1);
    }
    *word++ = ch;
    ch = getc(stdin);
    }                /* end of while */
    *word = '\0';        /* 原来的代码这里有问题 */
    return i;
}                /* end of nextin */

/* ------------------------------------------------------------------
* initw -- initialize the dictionary to contain no words at all
* ------------------------------------------------------------------ */
int initw(void)
{
    nwords = 0;
    return 1;
}                /* end of initw */

/* ------------------------------------------------------------------
* insertw -- insert a word in the dictionary
* ------------------------------------------------------------------ */
int insertw(const char *word)
{
    strcpy(dict[nwords], word);
    nwords++;
    return (nwords);
}                /* end of insertw */

/* ------------------------------------------------------------------
* deletew -- delete a word from the dictionary
* ------------------------------------------------------------------ */
int deletew(const char *word)
{
    int i;
    for (i = 0; i < nwords; i++) {
    if (strcmp(word, dict[i]) == 0) {
        nwords--;
        strcpy(dict[i], dict[nwords]);
        return (1);
    }
    }                /* end of for */
    return (0);
}                /* end of deletew */

/* ------------------------------------------------------------------
* lookupw -- look up a word in the dictionary
* ------------------------------------------------------------------ */
int lookupw(const char *word)
{
    int i;
    for (i = 0; i < nwords; i++) {
    if (strcmp(word, dict[i]) == 0) {
        return (1);
    }
    }                /* end of for */
    return (0);
}                /* end of lookupw */

这是一个简单的字典程序,即程序运行起来以后维护着一个字典库,用户可以向里面添加词语,也可以查询或删除词语。
当然,这个程序只能在同一台主机上运行。程序整个运行过程中,只需要完成如下几个步骤:
A、接受用户输入;
B、分析用户输入决定是否进行下面的步骤:
    1、初始化数据库;
    2、向数据库添加词语;
    3、查询或删除词语

任务分解
大家可以想到,对于一个大型系统,比如需要有很多人维护这个系统的数据。象上面这样独立的程序就不适用了,需要做成分布式系统:
即一个服务器维护着数据库,任何客户端都可以接受用户请求,客户端分析用户命令后提交给服务器去处理。
所以我们可能会把程序分成两部分:
客户端:接受用户输入,并判断用户输入内容的正确性,向服务器提交数据,等服务器返回消息
服务器端:维护数据,接受客户端命令并执行后返回结果。
所以我们把上面这个程序分解成下面两部分:

/* dict1.c -- main, nextin */
#include <stdio.h>
#include <stdlib.h>
#define MAXWORD 50        /* maximum length of a command or word */
/* ------------------------------------------------------------------
* main -- insert, delete, or lookup words in a dictionary as specified
* ------------------------------------------------------------------ */
int main(int argc, char *argv[])
{
    char word[MAXWORD + 1];    /* space to hold word from input line */
    char cmd;
    int wordlen;        /* length of input word */
    printf("Please input:\n");
    while (1) {
    wordlen = nextin(&cmd, word);
    if (wordlen < 0) {
        exit(0);
    }
    switch (cmd) {
    case 'I':        /* 初始化 */
        initw();
        printf("Dictionary initialized to empty.\n");
        break;
    case 'i':        /* 插入 */
        insertw(word);
        printf("%s inserted.\n", word);
        break;
    case 'd':        /* 删除 */
        if (deletew(word)) {
        printf("%s deleted.\n", word);
        } else {
        printf("%s not found.\n", word);
        }
        break;
    case 'l':        /* 查询 */
        if (lookupw(word)) {
        printf("%s was found.\n", word);
        } else {
        printf("%s was not found.\n", word);
        }
        break;
    case 'q':        /* 退出 */
        printf("Program quits.\n");
        exit(0);
        break;
    default:        /* 非法输入 */
        printf("command %c invalid.\n", cmd);
        break;
    }            /* end of switch */
    }                /* end of while */
    return 0;
}                /* end of main */

/* ------------------------------------------------------------------
* nextin -- read a command and(possibly) a word from the next input line
* ------------------------------------------------------------------ */
int nextin(char *cmd, char *word)
{
    int i, ch;
    ch = getc(stdin);
    while (isspace(ch)) {
    ch = getc(stdin);
    }                /* end of while */
    if (ch == EOF) {
    return (-1);
    }
    *cmd = (char) ch;
    ch = getc(stdin);
    while (isspace(ch)) {
    ch = getc(stdin);
    }                /* end of while */
    if (ch == EOF) {
    return (-1);
    }
    if (ch == '\n') {
    return (0);
    }
    i = 0;
    while (!isspace(ch)) {
    if (++i > MAXWORD) {
        printf("error: word too long.\n");
        exit(1);
    }
    *word++ = ch;
    ch = getc(stdin);
    }                /* end of while */
    *word = '\0';
    return i;
}                /* end of nextin */

/* dict2.c -- initw, insertw, deletew, lookupw */
#include <string.h>
#define MAXWORD 50        /* maximum length of a command or word */
#define DICTSIZ 100        /* maximum number of entries in dictionary. */
char dict[DICTSIZ][MAXWORD + 1];    /* storage for a dictionary of words */
int nwords = 0;            /* number of words in the dictionary */
/* ------------------------------------------------------------------
* initw -- initialize the dictionary to contain no words at all
* ------------------------------------------------------------------ */
int initw(void)
{
    nwords = 0;
    return 1;
}                /* end of initw */

/* ------------------------------------------------------------------
* insertw -- insert a word in the dictionary
* ------------------------------------------------------------------ */
int insertw(const char *word)
{
    strcpy(dict[nwords], word);
    nwords++;
    return (nwords);
}                /* end of insertw */

/* ------------------------------------------------------------------
* deletew -- delete a word from the dictionary
* ------------------------------------------------------------------ */
int deletew(const char *word)
{
    int i;
    for (i = 0; i < nwords; i++) {
    if (strcmp(word, dict[i]) == 0) {
        nwords--;
        strcpy(dict[i], dict[nwords]);
        return (1);
    }
    }                /* end of for */
    return (0);
}                /* end of deletew */

/* ------------------------------------------------------------------
* lookupw -- look up a word in the dictionary
* ------------------------------------------------------------------ */
int lookupw(const char *word)
{
    int i;
    for (i = 0; i < nwords; i++) {
    if (strcmp(word, dict[i]) == 0) {
        return (1);
    }
    }                /* end of for */
    return (0);
}                /* end of lookupw */

这两部分代码只是在功能上实现了分离,显然实现通讯的部分还没有,下面我们利用RPC来快速实现通讯。

利用RPC实现分布式系统
首先,建立一个RPC源文件,源代码rdict.x如下:

/* rdict.x */
/* RPC declarations for dictionary program */
const MAXWORD = 10;   /* maximum length of a command or word */
const DICTSIZ = 3;  /* number of entries in dictionary */
struct example      /* unused structure declared here to */
{
    int  exfield1;  /* illustrate how rpcgen builds XDR */
    char exfield2;  /* routines to convert structures */
};
/* ------------------------------------------------------------------
* RDICTPROG -- remote program that provides insert, delete, and lookup
* ------------------------------------------------------------------ */
program RDICTPROG  /* name of remote program ( not used ) */
{
    version RDICTVERS  /* declaration of version ( see below ) */
    {
        int INITW ( void )     = 1;  /* first procedure in this program */
        int INSERTW ( string ) = 2;  /* second procedure in this program */
        int DELETEW ( string ) = 3;  /* third procedure in this program */
        int LOOKUPW ( string ) = 4;  /* fourth procedure in this program */
    } = 1;  /* definition of the program version */
} = 0x30090949;  /* remote program number ( must be unique ) */

然后用下列命令产生服务器端函数rdict_srv_func.c:

rpcgen -Ss -o rdict_srv_func.c rdict.x

然后用下列命令产生客户端程序rdict_client.c:

rpcgen -Sc -o rdict_client.c rdict.x

/************关于本文档********************************************
*filename: 我是这样学习Linux下C语言编程的-利用RPC快速实现分布式系统
*purpose: 说明如何利用RPC快速进行客户端-服务器端C-S结构编程
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-02-27 19:20
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to:
*                Ubuntu 本程序在Ubuntu 6.10系统上测试完全正常
*                Google.com 我通过google搜索并参考了RPC编程相关的许多文章
*               网络安全焦点(www.xfocus.net) 我主要借鉴了此文 http://www.xfocus.net/articles/200009/10.html
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
然后用下列命令产生Makefile:

 rpcgen -Sm rdict.x > Makefile

Makefile文件原内容如下:

# This is a template Makefile generated by rpcgen

# Parameters

CLIENT = rdict_client
SERVER = rdict_server

SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = rdict.x

TARGETS_SVC.c = rdict_svc.c   rdict_xdr.c
TARGETS_CLNT.c = rdict_clnt.c   rdict_xdr.c
TARGETS = rdict.h rdict_xdr.c rdict_clnt.c rdict_svc.c   

OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags

CFLAGS += -g
LDLIBS += -lnsl
RPCGENFLAGS =

# Targets

all : $(CLIENT) $(SERVER)

$(TARGETS) : $(SOURCES.x)
        rpcgen $(RPCGENFLAGS) $(SOURCES.x)

$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)

$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)

$(CLIENT) : $(OBJECTS_CLNT)
        $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)

$(SERVER) : $(OBJECTS_SVC)
        $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)

 clean:
         $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)

动手修改Makefile,修改后内容如下:

# This is a template Makefile generated by rpcgen

# Parameters

CLIENT = rdict_client
SERVER = rdict_server

SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = rdict.x

TARGETS_SVC.c = rdict_svc.c   rdict_xdr.c rdict_srv_func.c
TARGETS_CLNT.c = rdict_clnt.c   rdict_xdr.c rdict_client.c
TARGETS = rdict.h rdict_xdr.c rdict_clnt.c rdict_svc.c

OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags

CFLAGS += -g
LDLIBS += -lnsl
RPCGENFLAGS =

# Targets

all : $(CLIENT) $(SERVER)

$(TARGETS) : $(SOURCES.x)
        rpcgen $(RPCGENFLAGS) $(SOURCES.x)

$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)

$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)

$(CLIENT) : $(OBJECTS_CLNT)
        $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)

$(SERVER) : $(OBJECTS_SVC)
        $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)

clean:
         $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) *~

修改客户端源代码rdict_client.c,把接受用户输入并分析用户输入内容的部分加到程序中来。修改后的代码为:

/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "rdict.h"

/* ------------------------------------------------------------------
* nextin -- read a command and(possibly) a word from the next input line
* ------------------------------------------------------------------ */
int nextin(char *cmd, char *word)
{
    int i, ch;
    ch = getc(stdin);
    while (isspace(ch)) {
    ch = getc(stdin);
    }                /* end of while */
    if (ch == EOF) {
    return (-1);
    }
    *cmd = (char) ch;
    ch = getc(stdin);
    while (isspace(ch)) {
    ch = getc(stdin);
    }                /* end of while */
    if (ch == EOF) {
    return (-1);
    }
    if (ch == '\n') {
    return (0);
    }
    i = 0;
    while (!isspace(ch)) {
    if (++i > MAXWORD) {
        printf("error: word too long.\n");
        exit(1);
    }
    *word++ = ch;
    ch = getc(stdin);
    }                /* end of while */
    *word = '\0';
    return i;
}                /* end of nextin */

void rdictprog_1(char *host)
{
    CLIENT *clnt;
    int *result_1;
    char *initw_1_arg;
    int *result_2;
    char *insertw_1_arg;
    int *result_3;
    char *deletew_1_arg;
    int *result_4;
    char *lookupw_1_arg;

#ifndef    DEBUG
    clnt = clnt_create(host, RDICTPROG, RDICTVERS, "udp");
    if (clnt == NULL) {
    clnt_pcreateerror(host);
    exit(1);
    }
#endif                /* DEBUG */
    char word[MAXWORD + 1];    /* space to hold word from input line */
    char cmd;
    int wordlen;        /* length of input word */
    while (1) {
    printf("\nPlease input:");
    wordlen = nextin(&cmd, word);
    if (wordlen < 0) {
        exit(0);
    }
    /* printf("\nYour cmd is:%c, your word is:%s\n", cmd, word); */
    switch (cmd) {
    case 'I':        /* 初始化 */
        result_1 = initw_1((void *) &initw_1_arg, clnt);
        /* printf("\nYour result is:%d\n", *result_1); */
        if (result_1 == (int *) NULL)
        clnt_perror(clnt, "call failed");
        else
        if(*result_1 ==0) printf("Dictionary initialized to empty.\n");
        else printf("Dictionary have already initialized.\n");
        break;
    case 'i':        /* 插入 */
        insertw_1_arg = word;
        result_2 = insertw_1(&insertw_1_arg, clnt);
        /* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_2, insertw_1_arg, strlen(insertw_1_arg)); */
        if (result_2 == (int *) NULL)
        clnt_perror(clnt, "call failed");
        else
        printf("%s inserted.\n", word);
        break;
    case 'd':        /* 删除 */
        deletew_1_arg = word;
        result_3 = deletew_1(&deletew_1_arg, clnt);
        /* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_3, deletew_1_arg, strlen(deletew_1_arg)); */
        if (result_3 == (int *) NULL)
        clnt_perror(clnt, "call failed");
        else
        printf("%s deleted.\n", word);
        break;
    case 'l':        /* 查询 */
        lookupw_1_arg = word;
        result_4 = lookupw_1(&lookupw_1_arg, clnt);
        /* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_4, lookupw_1_arg, strlen(lookupw_1_arg)); */
        if (result_4 == (int *) NULL)
        clnt_perror(clnt, "call failed");
        else
        if(*result_4 ==0) printf("%s found.\n", word);
        else printf("%s not found.\n", word);
        break;
    case 'q':        /* 退出 */
        printf("Program quits.\n");
        exit(0);
        break;
    default:        /* 非法输入 */
        printf("Command %c(%s) invalid.\n", cmd, word);
        break;
    }            /* end of switch */
    }                /* end of while */

#ifndef    DEBUG
    clnt_destroy(clnt);
#endif                /* DEBUG */
}


int main(int argc, char *argv[])
{
    char *host;

    if (argc < 2) {
    printf("usage: %s server_host\n", argv[0]);
    exit(1);
    }
    host = argv[1];
    rdictprog_1(host);
    exit(0);
}

同时修改服务器端代码rdict_srv_func.c,修改后内容为:

/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "rdict.h"

char dict[DICTSIZ][MAXWORD + 1];    /* storage for a dictionary of words */
int nwords = 0;            /* number of words in the dictionary */
char init_bool = 0;

int initw(void)
{
    if(init_bool) return 1;
    nwords = 0;
    init_bool = 1;
    return 0;
}                /* end of initw */

/* ------------------------------------------------------------------
* insertw -- insert a word in the dictionary
* ------------------------------------------------------------------ */
int insertw(const char *word)
{
    strcpy(dict[nwords%DICTSIZ], word);
    nwords++;
    return (nwords);
}                /* end of insertw */

/* ------------------------------------------------------------------
* deletew -- delete a word from the dictionary
* ------------------------------------------------------------------ */
int deletew(const char *word)
{
    int i;
    for (i = 0; i < nwords; i++) {
    if (strcmp(word, dict[i]) == 0) {
        nwords--;
        strcpy(dict[i], dict[nwords]);
        return (1);
    }
    }                /* end of for */
    return (0);
}                /* end of deletew */

/* ------------------------------------------------------------------
* lookupw -- look up a word in the dictionary
* ------------------------------------------------------------------ */
int lookupw(const char *word)
{
    int i;
    for (i = 0; i < nwords; i++) {
    if (strcmp(word, dict[i]) == 0) {
        return 0;
    }
    }                /* end of for */
    return 1;
}                /* end of lookupw */

int *initw_1_svc(void *argp, struct svc_req *rqstp)
{
    static int result;

    /*
     * insert server code here
     */

    result = initw();

    return &result;
}

int *insertw_1_svc(char **argp, struct svc_req *rqstp)
{
    static int result;

    /*
     * insert server code here
     */
    result = insertw(*argp);

    return &result;
}

int *deletew_1_svc(char **argp, struct svc_req *rqstp)
{
    static int result;

    /*
     * insert server code here
     */

    result = deletew(*argp);

    return &result;
}

int *lookupw_1_svc(char **argp, struct svc_req *rqstp)
{
    static int result;

    /*
     * insert server code here
     */

    result = lookupw(*argp);

    return &result;
}

至此,程序做好了。输入一个make命令就可以生成test_server和test_client这两个可执行程序了。
在一台机器上运行./test_server程序,在另外的客户机上运行./test_client server_ip就可以了。这里server_ip是运行着test_server程序的主机的IP地址。

分享到:
评论

相关推荐

    MATLAB-四连杆机构的仿真+项目源码+文档说明

    <项目介绍> - 四连杆机构的仿真 --m3_1.m: 位置问题求解 --m2_1.m: 速度问题求解 --FourLinkSim.slx: Simlink基于加速度方程的仿真 --FourLinkSim2.slx: Simscape简化模型仿真 --FourLinkSim3.slx: Simscape CAD模型仿真 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

    ridge_regression:用于岭回归的python代码(已实现以预测下个月的CO2浓度)

    ridge_regression 用于岭回归的python代码(已实现以预测下个月的CO2浓度) 资料可用性 文件 Ridge.py :标准函数和Ridge回归函数window_make.py :使用滑动窗口方法制作大小为p(窗口大小)的时间序列列表。 Final_version.ipynb :使用Co2数据对代码进行实验

    Polygon3-3.0.8-cp35-cp35m-win_amd64.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    【java毕业设计】风俗文化管理系统源码(ssm+mysql+说明文档+LW).zip

    功能说明: 系统主要分为系统管理员和用户两个部分,系统管理员主要功能包括首页,个人中心,用户管理,节日风俗管理,饮食风俗管理,服饰风俗管理,礼仪风俗管理,信仰风俗管理,建筑风俗管理,我的收藏管理,留言板管理,论坛管理,系统管理。 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    中国城市温度历史数据(2000-2020)-最新全集.zip

    中国城市温度历史数据(2000-2020)-最新全集.zip

    中国土地利用现状遥感监测数据(1km)-最新.zip

    中国土地利用现状遥感监测数据(1km)-最新.zip

    pgmagick-0.7.5-cp35-cp35m-win_amd64.whl.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    yolo算法-香烟盒子数据集-320张图像带标签-.zip

    yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值

    java资源Google API for Java

    java资源Google API for Java提取方式是百度网盘分享地址

    中国分地区地级市泰尔指数数据集(2000-2019).zip

    中国分地区地级市泰尔指数数据集(2000-2019).zip

    【java毕业设计】高职院校教学中心可视化教学分析系统源码(ssm+mysql+说明文档).zip

    环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    【java毕业设计】整体衣柜定制系统源码(ssm+mysql+说明文档).zip

    环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    【java毕业设计】房屋出租系统源码(ssm+mysql+说明文档+LW).zip

    功能说明: 系统功能实现了首页,房源信息,交流论坛,公告资讯,个人中心,后台管理等功能。系统的后台实现了个人中心,用户管理,房东管理,房源类型管理,房源信息管理,在线咨询管理,预约信息管理,订单信息管理,签订信息管理,申请退租管理,交流论坛,系统管理等功能的添加、删除和修改。 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea Maven包:Maven3.3及以上 服务器:tomcat7及以上

    yolo算法-电线杆数据集-1493张图像带标签-.zip

    yolo算法-电线杆数据集-1493张图像带标签-.zip;yolo算法-电线杆数据集-1493张图像带标签-.zip;yolo算法-电线杆数据集-1493张图像带标签-.zip

    安装包eclipse-jee-neon-3-win32-x86-64

    安装包eclipse-jee-neon-3-win32-x86_64提取方式是百度网盘分享地址

    param-1.12.2-py2.py3-none-any.whl.rar

    PartSegCore_compiled_backend-0.12.0a0-cp36-cp36m-win_amd64.whl.rar

    Pillow_SIMD-6.0.0.post0+avx2-cp27-cp27m-win_amd64.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    peewee-3.14.10-cp37-cp37m-win32.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

    中国各省GDP及农业主要指标数据集(1999-2019).zip

    中国各省GDP及农业主要指标数据集(1999-2019).zip

    ‌Nginx事件驱动模型深度解析‌

    ‌Nginx事件驱动模型深度解析‌

Global site tag (gtag.js) - Google Analytics