第16章 Sun RPC

RPC:远程过程调用






默认情况下服务器并不多线程化:

rpcgen -C data.x -DDEBUG
gcc server.c data_svc.c data_xdr.c -o server
gcc client.c data_clnt.c data_xdr.c -o client

多线程化:(-M 生成线程安全代码 -A 让服务器根据请求自动创建线程)

rpcgen -C data.x -DDEBUG -M
gcc server.c data_svc.c data_xdr.c -o server
gcc client.c data_clnt.c data_xdr.c -o client

#include <rpc/rpc.h>

char *clnt_sperror(CLIENT *rpch, char *s);
CLIENT *clnt_create(char *host, unsigned long prog, unsigned long vers, char *proto);
void clnt_destroy(CLIENT* cl);//显式终止一个客户的TCP连接
bool_t clnt_control(CLIENT* cl, unsigned int request, char* ptr);//request==CLGET_TIMEOUT/*总超时*/,request==CLGET_RETRY_TIMEOUT/*重试超时(UDP)*/
int svc_dg_enablecache(SVCXPRT* xprt, unsigned long size);//启用UDP高速缓存,使重复的请求不会多次调用过程

#include <rpc/clnt_stat.h>
//RPC_SUCCESS

data.x

struct square_in
{
    long arg1;
};

struct square_out
{
    long res1;
};

program SQUARE_PROG/*RPC程序*/
{
    version SQUARE_VERS
    {
        square_out SQUAREPROC(square_in) = 1;/*过程*/
    }=2;/*版本号*/
}=0x31230000;/*程序号*/

server.c

#include <unistd.h>
#include "data.h"

square_out* squareproc_1_svc(square_in* inp, struct svc_req* rqstp)
{
    static square_out out;

    printf("arg = %ld\n", inp->arg1);
    sleep(5);
    out.res1 = inp->arg1 * inp->arg1;
    printf("arg = %ld\n", inp->arg1);

    return &out;
}

bool_t squareproc_2_svc(square_in* inp, square_out* outp, struct svc_req* rqstp)
{
    printf("arg = %ld\n", inp->arg1);
    if(rqstp->rq_cred.oa_flavor == AUTH_SYS)
    {
        struct authunix_parms* au;
        au = (struct authunix_parms*)rqstp->rq_clntcred;
        printf("AUTH_SYS: host %s, uid %ld, gid %ld\n",
               au->aup_machname, (long)au->aup_uid, (long)au->aup_gid);
    }
    sleep(5);
    outp->res1 = inp->arg1 * inp->arg1;
    printf("arg = %ld\n", inp->arg1);
    
    return TRUE;
}

int square_prog_2_freeresult(SVCXPRT* transp, xdrproc_t xdr_result, caddr_t result)
{
    xdr_free(xdr_result, result);

    return 1;
}

client.c

#include "data.h"

int main(int argc, const char* argv[])
{
    CLIENT* cl;
    square_in in;
    square_out out;
    struct timeval tv;

    if(argc != 3)
    {
        printf("usage : client <hostname> <integer-value>\n");
        exit(-1);
    }

    cl = clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "udp");

    auth_destroy(cl->cl_auth);//销毁先前句柄关联的认证,空认证
    cl->cl_auth = authunix_create_default();//创建默认的Unix认证结构

    tv.tv_sec = 30;
    tv.tv_usec = 0;
    clnt_control(cl, CLSET_TIMEOUT, (char*)&tv);
    clnt_control(cl, CLSET_RETRY_TIMEOUT, (char*)&tv);

    if(clnt_control(cl, CLGET_TIMEOUT, (char*)&tv))
        printf("timeout = %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec);
    if(clnt_control(cl, CLGET_RETRY_TIMEOUT, (char*)&tv))
        printf("retry timeout = %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec);

    in.arg1 = atol(argv[2]);
    if(squareproc_2(&in, &out, cl) != RPC_SUCCESS)
    {
        printf("%s", clnt_sperror(cl, argv[1]));
        exit(-1);
    }
    printf("result : %ld\n", out.res1);

    return 0;
}
github: https://github.com/gongluck/unpv22-notes.git

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值