Linux编程之从零开始搭建RPC分布式系统
#define MY_RPC_PROG_NUM 0x38000010 //程序号 struct my_io_data_s //定义消息结构
{
int mtype;
int len;
char data[];
}; typedef struct my_io_data_s my_io_data_t; program MY_RPC_PROG { version MY_RPC_VERS1 {
int MY_RPCC(my_io_data_t) = ; /* 过程号 = 1 */
} = ; /* Version number = 1 */ version MY_RPC_VERS2 {
my_io_data_t MY_RPCC(my_io_data_t) = ; /* 过称号 = 1 */
} = ; /* Version number = 2 */ } = MY_RPC_PROG_NUM; /* Program number */
程序号范围
|
简述
|
0x00000000 - 0x1FFFFFFF
|
由Sun公司定义,提供特定服务
|
0x20000000 - 0x3FFFFFFF
|
由程序员自己定义,提供本地服务或用于调试
|
0x40000000 - 0x5FFFFFFF
|
用于短时间使用的程序,例如回调程序
|
0x60000000 - 0xFFFFFFFF
|
保留程序号
|

/*
* Please do not edit this file.
* It was generated using rpcgen.
*/ #ifndef _MY_H_RPCGEN
#define _MY_H_RPCGEN #include <rpc/rpc.h> #ifdef __cplusplus
extern "C" {
#endif struct my_io_data_s {
int mtype;
int len;
char data[];
};
typedef struct my_io_data_s my_io_data_s; typedef my_io_data_s my_io_data_t; #define MY_RPC_PROG 666
#define MY_RPC_VERS1 1 #if defined(__STDC__) || defined(__cplusplus)
#define MY_RPCC 1
extern int * my_rpcc_1(my_io_data_t *, CLIENT *);
extern int * my_rpcc_1_svc(my_io_data_t *, struct svc_req *);
extern int my_rpc_prog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */
#define MY_RPCC 1
extern int * my_rpcc_1();
extern int * my_rpcc_1_svc();
extern int my_rpc_prog_1_freeresult ();
#endif /* K&R C */
#define MY_RPC_VERS2 2 #if defined(__STDC__) || defined(__cplusplus)
extern my_io_data_t * my_rpcc_2(my_io_data_t *, CLIENT *);
extern my_io_data_t * my_rpcc_2_svc(my_io_data_t *, struct svc_req *);
extern int my_rpc_prog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */
extern my_io_data_t * my_rpcc_2();
extern my_io_data_t * my_rpcc_2_svc();
extern int my_rpc_prog_2_freeresult ();
#endif /* K&R C */ /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_my_io_data_s (XDR *, my_io_data_s*);
extern bool_t xdr_my_io_data_t (XDR *, my_io_data_t*); #else /* K&R C */
extern bool_t xdr_my_io_data_s ();
extern bool_t xdr_my_io_data_t (); #endif /* K&R C */ #ifdef __cplusplus
}
#endif #endif /* !_MY_H_RPCGEN */
my_clnt.c:
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/ #include <memory.h> /* for memset */
#include "my.h" /* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { , }; int *
my_rpcc_1(my_io_data_t *argp, CLIENT *clnt)
{
static int clnt_res; memset((char *)&clnt_res, , sizeof(clnt_res));
if (clnt_call (clnt, MY_RPCC,
(xdrproc_t) xdr_my_io_data_t, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
} my_io_data_t *
my_rpcc_2(my_io_data_t *argp, CLIENT *clnt)
{
static my_io_data_t clnt_res; memset((char *)&clnt_res, , sizeof(clnt_res));
if (clnt_call (clnt, MY_RPCC,
(xdrproc_t) xdr_my_io_data_t, (caddr_t) argp,
(xdrproc_t) xdr_my_io_data_t, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
my_svc.c
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/ #include "my.h"
#include <stdio.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h> #ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif static void
my_rpc_prog_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
my_io_data_t my_rpcc_1_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *); switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return; case MY_RPCC:
_xdr_argument = (xdrproc_t) xdr_my_io_data_t;
_xdr_result = (xdrproc_t) xdr_int;
local = (char *(*)(char *, struct svc_req *)) my_rpcc_1_svc;
break; default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, , sizeof (argument));
if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
exit ();
}
return;
} static void
my_rpc_prog_2(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
my_io_data_t my_rpcc_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *); switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return; case MY_RPCC:
_xdr_argument = (xdrproc_t) xdr_my_io_data_t;
_xdr_result = (xdrproc_t) xdr_my_io_data_t;
local = (char *(*)(char *, struct svc_req *)) my_rpcc_2_svc;
break; default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, , sizeof (argument));
if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
exit ();
}
return;
} int
main (int argc, char **argv)
{
register SVCXPRT *transp; pmap_unset (MY_RPC_PROG, MY_RPC_VERS1);
pmap_unset (MY_RPC_PROG, MY_RPC_VERS2); transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create udp service.");
exit();
}
if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS1, my_rpc_prog_1, IPPROTO_UDP)) {
fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS1, udp).");
exit();
}
if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS2, my_rpc_prog_2, IPPROTO_UDP)) {
fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS2, udp).");
exit();
} transp = svctcp_create(RPC_ANYSOCK, , );
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create tcp service.");
exit();
}
if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS1, my_rpc_prog_1, IPPROTO_TCP)) {
fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS1, tcp).");
exit();
}
if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS2, my_rpc_prog_2, IPPROTO_TCP)) {
fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS2, tcp).");
exit();
} svc_run ();
fprintf (stderr, "%s", "svc_run returned");
exit ();
/* NOTREACHED */
}
my_xdr.c
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/ #include "my.h" bool_t
xdr_my_io_data_s (XDR *xdrs, my_io_data_s *objp)
{
register int32_t *buf; int i;
if (!xdr_int (xdrs, &objp->mtype))
return FALSE;
if (!xdr_int (xdrs, &objp->len))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->data, ,
sizeof (char), (xdrproc_t) xdr_char))
return FALSE;
return TRUE;
} bool_t
xdr_my_io_data_t (XDR *xdrs, my_io_data_t *objp)
{
register int32_t *buf; if (!xdr_my_io_data_s (xdrs, objp))
return FALSE;
return TRUE;
}
/*
* 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 "my.h" void
my_rpc_prog_1(char *host)
{
CLIENT *clnt;
int *result_1;
my_io_data_t my_rpcc_1_arg; #ifndef DEBUG
clnt = clnt_create (host, MY_RPC_PROG, MY_RPC_VERS1, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit ();
}
#endif /* DEBUG */ result_1 = my_rpcc_1(&my_rpcc_1_arg, clnt);
if (result_1 == (int *) NULL) {
clnt_perror (clnt, "call failed");
}
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
} void
my_rpc_prog_2(char *host)
{
CLIENT *clnt;
my_io_data_t *result_1;
my_io_data_t my_rpcc_2_arg; #ifndef DEBUG
clnt = clnt_create (host, MY_RPC_PROG, MY_RPC_VERS2, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit ();
}
#endif /* DEBUG */ result_1 = my_rpcc_2(&my_rpcc_2_arg, clnt);
if (result_1 == (my_io_data_t *) NULL) {
clnt_perror (clnt, "call failed");
}
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
} int
main (int argc, char *argv[])
{
char *host; if (argc < ) {
printf ("usage: %s server_host\n", argv[]);
exit ();
}
host = argv[];
my_rpc_prog_1 (host);
my_rpc_prog_2 (host);
exit ();
}
/*
* 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 "my.h" int *
my_rpcc_1_svc(my_io_data_t *argp, struct svc_req *rqstp)
{
static int result; /*
* insert server code here
*/ return &result;
} my_io_data_t *
my_rpcc_2_svc(my_io_data_t *argp, struct svc_req *rqstp)
{
static my_io_data_t result; /*
* insert server code here
*/ return &result;
}
/*
* 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 "my.h" void
my_rpc_prog_1(char *host)
{
CLIENT *clnt;
int *result_1;
my_io_data_t my_rpcc_1_arg; #ifndef DEBUG
clnt = clnt_create (host, MY_RPC_PROG, MY_RPC_VERS1, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit ();
}
#endif /* DEBUG */ result_1 = my_rpcc_1(&my_rpcc_1_arg, clnt);
if (result_1 == (int *) NULL) {
clnt_perror (clnt, "call failed");
}
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
} void
my_rpc_prog_2(char *host)
{
CLIENT *clnt;
my_io_data_t *result_1;
my_io_data_t my_rpcc_2_arg; #ifndef DEBUG
clnt = clnt_create (host, MY_RPC_PROG, MY_RPC_VERS2, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit ();
}
#endif /* DEBUG */
my_rpcc_2_arg.mtype = ;
my_rpcc_2_arg.len = ;
result_1 = my_rpcc_2(&my_rpcc_2_arg, clnt);
if (result_1 == (my_io_data_t *) NULL) {
clnt_perror (clnt, "call failed");
}
fprintf(stderr,"recv msg from server! mtype:%d len:%d \n",result_1->mtype,result_1->len);
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
} int
main (int argc, char *argv[])
{
char *host; if (argc < ) {
printf ("usage: %s server_host\n", argv[]);
exit ();
}
host = argv[];
//my_rpc_prog_1 (host);
my_rpc_prog_2 (host);
exit ();
}
值得注意的是,我们client使用的是UDP协议,当然我们用户也可以根据自己需要选用TCP协议进行开发。
my_server.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 "my.h" int *
my_rpcc_1_svc(my_io_data_t *argp, struct svc_req *rqstp)
{
static int result; /*
* insert server code here
*/
return &result;
} my_io_data_t *
my_rpcc_2_svc(my_io_data_t *argp, struct svc_req *rqstp)
{
static my_io_data_t result; /*
* insert server code here
*/
printf("recv msg from client! len:%d, mt:%d \n",argp->len,argp->mtype);
result.mtype = ;
result.len = ;
return &result;
}

client端
my_client、my_server.c、my_clnt.c、my.h
首先我们重新定义一下客户端和服务器端通信消息的格式。
typedef struct my_msg_hdr_s
{
int mtype;
int len;
}my_msg_hdr_t; typedef struct my_msg_s
{
my_msg_hdr_t msg_hdr;
int para1;
int para2;
int result;
}my_msg_t;
/*
* 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 "my.h"
#include "rpc_msg.h" int my_rpc_prog_1(char *host, my_io_data_t* in_msg)
{
CLIENT *clnt;
int *result_1; #ifndef DEBUG
clnt = clnt_create (host, MY_RPC_PROG, MY_RPC_VERS1, "udp");
if (clnt == NULL)
{
printf("Fail to create rpc client1!\n");
return -;
}
#endif /* DEBUG */ result_1 = my_rpcc_1(in_msg, clnt);
if (result_1 == (int *) NULL)
{
clnt_perror (clnt, "call failed");
return -;
} return ; } my_io_data_t * my_rpc_prog_2(char *host, my_io_data_t* in_msg)
{
CLIENT *clnt;
my_io_data_t *result_1 = NULL; #ifndef DEBUG
clnt = clnt_create (host, MY_RPC_PROG, MY_RPC_VERS2, "udp");
if (clnt == NULL)
{
printf("Fail to create rpc client1!\n");
return NULL;
}
#endif /* DEBUG */ result_1 = my_rpcc_2(in_msg, clnt);
if (result_1 == (my_io_data_t *) NULL)
{
clnt_perror (clnt, "call failed");
return NULL;
} return result_1; } void get_compute_result(char *host, int type, int para1, int para2)
{
my_io_data_t in_msg;
my_msg_t* rsp;
my_io_data_t* out_msg;
my_msg_t* req = (my_msg_t*)&in_msg; memset(&in_msg, , sizeof(in_msg));
req->msg_hdr.mtype = type;
req->msg_hdr.len = sizeof(in_msg) - sizeof(my_msg_hdr_t);
req->para1 = para1;
req->para2 = para2; out_msg = my_rpc_prog_2(host, &in_msg); rsp = (my_msg_t*)out_msg; if(rsp == NULL)
{
printf("RPC call fail!\n");
return;
} printf("compute result is %d\n",rsp->result); } void server_switch(char *host, int type)
{
my_io_data_t msg;
my_msg_t* in_msg = (my_msg_t*)&msg;
memset(&msg, , sizeof(msg));
in_msg->msg_hdr.mtype = type;
in_msg->msg_hdr.len = sizeof(msg) - sizeof(my_msg_hdr_t); if(my_rpc_prog_1(host, &msg))
{
printf("enable server fail!\n");
}
printf("Configure server successfully!\n");
} int main (int argc, char *argv[])
{
server_switch(SERVER_IP, RPC_enable); //server start
sleep();
get_compute_result(SERVER_IP, RPC_ADD, , );
sleep();
get_compute_result(SERVER_IP, RPC_SUB, , );
sleep();
get_compute_result(SERVER_IP, RPC_MUL, , );
sleep();
get_compute_result(SERVER_IP, RPC_DIV, , );
sleep();
server_switch(SERVER_IP, RPC_disable); //server close
return ;
}
/*
* 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 "my.h"
#include "rpc_msg.h" int* my_rpcc_1_svc(my_io_data_t *argp, struct svc_req *rqstp)
{
static int result; switch(argp->mtype)
{
case RPC_enable:
printf("server start!\n");
break; case RPC_disable:
printf("server close!\n");
break; default:
break;
} return &result;
} my_io_data_t* my_rpcc_2_svc(my_io_data_t *argp, struct svc_req *rqstp)
{
static my_io_data_t result;
my_msg_t* out = (my_msg_t*)&result;
my_msg_t* in = (my_msg_t*)argp; switch(in->msg_hdr.mtype)
{
case RPC_ADD:
out->result = in->para1 + in->para2;
break; case RPC_SUB:
out->result = in->para1 - in->para2;
break; case RPC_MUL:
out->result = in->para1 * in->para2;
break; case RPC_DIV:
out->result = in->para1/in->para2;
break; default:
break;
} return &result;
}
#define SERVER_IP "172.0.5.183" enum RPC_REQ_TYPE_1
{
RPC_enable,
RPC_disable,
}; enum RPC_REQ_TYPE_2
{
RPC_ADD,
RPC_SUB,
RPC_MUL,
RPC_DIV,
}; typedef struct my_msg_hdr_s
{
int mtype;
int len;
}my_msg_hdr_t; typedef struct my_msg_s
{
my_msg_hdr_t msg_hdr;
int para1;
int para2;
int result;
}my_msg_t;
my_clnt.c:
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/ #include <memory.h> /* for memset */
#include "my.h" /* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { , }; int *
my_rpcc_1(my_io_data_t *argp, CLIENT *clnt)
{
static int clnt_res; memset((char *)&clnt_res, , sizeof(clnt_res));
if (clnt_call (clnt, MY_RPCC,
(xdrproc_t) xdr_my_io_data_t, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
} my_io_data_t *
my_rpcc_2(my_io_data_t *argp, CLIENT *clnt)
{
static my_io_data_t clnt_res; memset((char *)&clnt_res, , sizeof(clnt_res));
if (clnt_call (clnt, MY_RPCC,
(xdrproc_t) xdr_my_io_data_t, (caddr_t) argp,
(xdrproc_t) xdr_my_io_data_t, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
my.h
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/ #ifndef _MY_H_RPCGEN
#define _MY_H_RPCGEN #include <rpc/rpc.h> #ifdef __cplusplus
extern "C" {
#endif struct my_io_data_s {
int mtype;
int len;
char data[];
};
typedef struct my_io_data_s my_io_data_s; typedef my_io_data_s my_io_data_t; #define MY_RPC_PROG 666
#define MY_RPC_VERS1 1 #if defined(__STDC__) || defined(__cplusplus)
#define MY_RPCC 1
extern int * my_rpcc_1(my_io_data_t *, CLIENT *);
extern int * my_rpcc_1_svc(my_io_data_t *, struct svc_req *);
extern int my_rpc_prog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */
#define MY_RPCC 1
extern int * my_rpcc_1();
extern int * my_rpcc_1_svc();
extern int my_rpc_prog_1_freeresult ();
#endif /* K&R C */
#define MY_RPC_VERS2 2 #if defined(__STDC__) || defined(__cplusplus)
extern my_io_data_t * my_rpcc_2(my_io_data_t *, CLIENT *);
extern my_io_data_t * my_rpcc_2_svc(my_io_data_t *, struct svc_req *);
extern int my_rpc_prog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */
extern my_io_data_t * my_rpcc_2();
extern my_io_data_t * my_rpcc_2_svc();
extern int my_rpc_prog_2_freeresult ();
#endif /* K&R C */ /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_my_io_data_s (XDR *, my_io_data_s*);
extern bool_t xdr_my_io_data_t (XDR *, my_io_data_t*); #else /* K&R C */
extern bool_t xdr_my_io_data_s ();
extern bool_t xdr_my_io_data_t (); #endif /* K&R C */ #ifdef __cplusplus
}
#endif #endif /* !_MY_H_RPCGEN */

Linux编程之从零开始搭建RPC分布式系统的更多相关文章
- 【Linux编译环境的搭建】Linux都没有,怎么学Linux编程?
本文准备从0开始,一步步搭建一套属于自己的多节点Linux系统环境,这将是后续学Linux.用Linux.Linux环境编程.应用和项目部署.工具实验等一系列学习和实践的基石,希望对小伙伴们有帮助. ...
- 孤荷凌寒自学python第六十一天在Fedora28版的linux系统上找搭建本地Mongodb数据服务
孤荷凌寒自学python第六十一天在Fedora28版的linux系统上找搭建本地Mongodb数据服务 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第七天.成功在本地搭建 ...
- 在阿里云服务器(ECS)上从零开始搭建nginx服务器
本文介绍了如何在阿里云服务器上从零开始搭建nginx服务器.阿里云服务器(ECS)相信大家都不陌生,感兴趣的同学可以到http://www.aliyun.com/product/ecs去购买,或到体验 ...
- 02shell编程环境的搭建
02shell编程环境的搭建 [02]Shell编程 02shell编程环境的搭建 在不同的操作系统上搭建shell编程环境 Linux Windows Mac 编辑器的选择 系统环境的搭建 注: 选 ...
- Linux编程之给你的程序开后门
这里说的"后门"并不是教你做坏事,而是让你做好事,搭建自己的调试工具更好地进行调试开发.我们都知道,当程序发生异常错误时,我们需要定位到错误,有时我们还想,我们在不修改程序的前提下 ...
- linux常用服务软件搭建及使用技巧
一.Webmin安装: Webmin 是一个基于浏览器的管理工具,可以应用于Linux 和其他一些平台,提供了可以完成很多管理和操作任务的图形化界面 •安装完成后,root 用户会被自动创建,密码为系 ...
- 【HADOOP】| 环境搭建:从零开始搭建hadoop大数据平台(单机/伪分布式)-下
因篇幅过长,故分为两节,上节主要说明hadoop运行环境和必须的基础软件,包括VMware虚拟机软件的说明安装.Xmanager5管理软件以及CentOS操作系统的安装和基本网络配置.具体请参看: [ ...
- AI应用开发实战 - 从零开始搭建macOS开发环境
AI应用开发实战 - 从零开始搭建macOS开发环境 本视频配套的视频教程请访问:https://www.bilibili.com/video/av24368929/ 建议和反馈,请发送到 https ...
- 【从零开始搭建自己的.NET Core Api框架】(七)授权认证进阶篇
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
随机推荐
- Git GitHub的使用
Git的工作区示意 GIT总结 使用git github也一段时间突然发现还是少了一些总结,那就从这儿开始吧! (1)git的配置,这儿就从单独的安装配置开始 安装:sudo yum install ...
- ArcEngine部分工作总结
Arcengine工作总结地物点查询本部分可以在一个窗体中实现,也可以在两个窗体中实现.由于工作要求本人是在两个窗体中实现的:弹出窗体的名称为FormQuery主窗体单机查询时间的代码FormQuer ...
- Android SQLITE数据类型
2011-6-24 15:14:00来源:Sql SQLITE数据类型 SQLite与其他常见的DBMS的最大不同是它对数据类型的支持.其他常见的DBMS通常支持强类型的数据,也就是每一列的类型都 ...
- mysql连接字符集default
用mysql客户端工具输入中文数据报错,或乱码问题解决 数据库字符集为latin1时 用mysql工具,然后选择连接>l连接属性>高级>字符集选择default
- iOS开发——WAVE音频文件解析
WAV文件也分了好几类,相应的非数据信息存储在文件的头部,下面简单的提一下,然后在最后重点介绍44字节的那种,一般用的都是这个. 1.8KHz采样.16比特量化的线性PCM语音信号的WAVE文件头格式 ...
- css颜色渐变在不同浏览器的设置
在web开发中,难免会遇到浏览器之间的兼容问题,关于Css设置颜色渐变下面有解决的办法,直接上代码: 适用于谷歌浏览器: background: -webkit-gradient(linear, 0 ...
- tp框架
<?php namespace Admin\Controller; use Think\Controller; class DengluController extends Controller ...
- svn无法提交
svn无法提交, 错误信息:Commit failed. svn: E200007: CHECKOUT can only be performed on a version resource... 解 ...
- IOS开发-ObjC-NSString
NSString是oc语言Foundation框架中常用的类,我根据每个方法的功能将NSString的常用方法分为创建字符串.初始化字符串.判断和比较字符串.大写和小写相互转化.字符串的截取.类型转换 ...
- mySql 分段查询
准备: 创建一个成绩表 Create table grade (id integer, score integer); 插入数据(只有id每次加一,score是1到100的随机数,java生成): p ...