Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4022909
  • 博文数量: 251
  • 博客积分: 11197
  • 博客等级: 上将
  • 技术积分: 6862
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-05 14:41
个人简介

@HUST张友东 work@taobao zyd_com@126.com

文章分类

全部博文(251)

文章存档

2014年(10)

2013年(20)

2012年(22)

2011年(74)

2010年(98)

2009年(27)

分类: LINUX

2010-07-14 09:34:38

在项目中遇到一个问题,当客户端通过SUN RPC进行远程过程调用时,服务器如何获取调用方的IP地址,由于RPCsocket的封装,在send/recv的调用中都能获取数据包的源IP地址,故RPC肯定又能提供这样的接口。

 

最开始的需求源于DNFS的存储节点周期性的向元数据服务器发送心跳信息,当收到心跳信息后,服务器需要辨别心跳信息来自哪一个存储节点,WCW师兄的方法是在调用参数中增加IP地址一项,这种方法是可以的,但获取本地IP地址的方法需要指明网卡接口名,导致程序从一台以eth0为网卡接口名的机器移到一台以eth1为网卡接口名的机器上都需要更改存储节点的配置文件,但存储节点很多时,使用起来很不方便。

 

N个月前曾经就寻求过RPC服务器获取调用方IP地址的方法,以为RPC库会提供这样的借口,大致浏览了下man手册里的一些接口,发现svc_getcaller似乎能提供我需要的功能,其原型为struct sockaddr_in *svc_getcaller(SVCXPRT *xprt),但实现RPC服务器函数时,我们只能操作第三个参数struct svc_req,而SVCXPRT只显示出现在rpcgen自动生成的svc文件中,然后我就放弃了。

 

今天coding的时候,又碰到这个需求,于是我想修改rpc的认证方式能否达到这个目的,于是又回过头看了一下RPCUnix认证方式,可通过AUTH *authunix_create(char *host, int uid, int gid, int len, int *aup_gids)构造unix认证(包含主机名,uidgid的信息)的内容,使用unix认证方式后,服务器能获取unix认证方式传递过来的内容,通过这种方式获取客户端信息跟将信息放到调用参数中差不多,基本上没有任何帮助。

 

虽然这条路没有成功,但在测试unix认证的时候,发现struct svc_req中除了包含程序号,版本号,认证方式等信息,还有一个指向SVCXPRT传输点的指针,于是问题迎刃而解,svc_getcaller也就派上用场了。

 

RPC服务器实现中加入如下代码即可打印出RPC调用方的IP地址。

 

struct sockaddr_in *si = svc_getcaller(rqstp->rq_xprt);

char *ipp = inet_ntoa(si->sin_addr);

printf("%s\n", ipp);

阅读(6609) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

no_error2014-11-05 11:17:39

大神!!!我现在用客户端用clnt_broadcas()函数向以太网中发广播包,服务器接收广播包并用svc_sendreply()函数返回自己的信息,这样客户端就可以知道这个以太网上所有的服务器的IP信息等等。可是客户端的广播包发过后有的主机可以接受,有的不可以接受,这是怎么回事呀,求大神指点!!!!

chinaunix网友2010-07-16 10:45:25

继续努力,要走的路还长!