⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 559.htm

📁 unix高级编程原吗
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="15.htm">上一层</a>][<a href="560.htm">下一篇</a>]
<hr><p align="left"><small>  <br>

  <br>

  <br>

发信人: cloudsky (小四), 信区: Security ;32mWWW-POSTm <br>

  <br>

标  题: RPC/XDR/NFS系列之----RPC编程初战(1) <br>

  <br>

发信站: 武汉白云黄鹤站 (Sun Feb 20 11:48:46 2000) , 站内信件 <br>

  <br>

  <br>

  <br>

★ 启动服务器执行客户机 <br>

  <br>

  <br>

  <br>

[scz@ /home/scz/src]> ./rdictd & <br>

  <br>

[1] 553 <br>

  <br>

[scz@ /home/scz/src]> ./rdict <br>

  <br>

Please input: <br>

  <br>

  <br>

II <br>

  <br>

Dictionary initialized to empty. <br>

  <br>

i hellow <br>

  <br>

hellow inserted. <br>

  <br>

i orld <br>

  <br>

orld inserted. <br>

  <br>

l hellow <br>

  <br>

hellow was found. <br>

  <br>

d hellow <br>

  <br>

hellow deleted. <br>

  <br>

qq <br>

  <br>

  <br>

Program quits. <br>

  <br>

[scz@ /home/scz/src]> kill %1 <br>

  <br>

[scz@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

★ 分离服务器和客户机 <br>

  <br>

  <br>

  <br>

修改rdict.c中的 #define RMACHINE "localhost"  /* name of remote <br>

  <br>

machine */ <br>

  <br>

我测试的时候rdictd运行在server上,rdict运行在higgs上,所以改成了 <br>

  <br>

  <br>

  <br>

#define RMACHINE "server"  /* name of remote machine */ <br>

  <br>

  <br>

  <br>

  <br>

重新编译生成rdict,然后用sftp上传到higgs上,ssh到higgs,chmod +x rdict, <br>

  <br>

运 <br>

  <br>

行rdict的效果和前面是一样的。至此,一个完整的可以测试使用的真正意义上的 <br>

  <br>

RPC <br>

  <br>

程序完成了,包括client端和server端。 <br>

  <br>

  <br>

  <br>

★ rpcinfo的使用以及portmap原理简介(重要) <br>

  <br>

  <br>

  <br>

现在让我们从higgs上来看看server <br>

  <br>

  <br>

  <br>

  <br>

[scz@ /home/scz/src]> /usr/sbin/rpcinfo <br>

  <br>

Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ] <br>

  <br>

       rpcinfo [ -n portnum ] -t host prognum [ versnum ] <br>

  <br>

       rpcinfo -p [ host ] <br>

  <br>

       rpcinfo -b prognum versnum <br>

  <br>

       rpcinfo -d prognum versnum <br>

  <br>

[scz@ /home/scz/src]> /usr/sbin/rpcinfo -p server <br>

  <br>

   program vers proto   port <br>

  <br>

    100000    2   tcp    111  rpcbind <br>

  <br>

    100000    2   udp    111  rpcbind <br>

  <br>

 805898569    1   udp   1029 <br>

  <br>

  <br>

 805898569    1   tcp   1036 <br>

  <br>

[scz@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

0x30090949 = 805898569,现在知道rpcinfo的这个program数字是什么了吧, <br>

  <br>

就是远程程序号呀。后面的1就是远程程序版本号。tcp表示使用tcp协议作为 <br>

  <br>

底层支持协议。回顾rdict.c中的语句: <br>

  <br>

  <br>

  <br>

handle = clnt_create( RMACHINE, RDICTPROG, RDICTVERS, "tcp" ); <br>

  <br>

  <br>

  <br>

第一个参数是远程主机名,第二个参数是远程程序号,第三个参数是远程 <br>

  <br>

程序版本号,第四个参数指定底层支持协议。注意到从higgs上运行rpcinfo <br>

  <br>

  <br>

报告出来的结果,说明rdictd同时支持了tcp和udp,此时如果修改rdict.c <br>

  <br>

中的语句: <br>

  <br>

  <br>

  <br>

handle = clnt_create( RMACHINE, RDICTPROG, RDICTVERS, "udp" ); <br>

  <br>

  <br>

  <br>

同样可以达到效果(测试过)。当然,在实际应用中选择tcp还是udp要根据网 <br>

  <br>

络状况具体决定。 <br>

  <br>

  <br>

  <br>

rpcinfo报告出来的第四个数据port是什么意思呢,这里简单介绍一下。 <br>

  <br>

因为远程程序号总共32bit,超出了端口的16bit范围,所以不能直接在远程 <br>

  <br>

程序号和端口号之间建立映射,于是产生了动态端口获得的概念。rpc server <br>

  <br>

  <br>

通过操作系统获得一个当前空闲的端口号,然后想向端口映射器 <br>

  <br>

portmap/rpcbind <br>

  <br>

注册这种映射关系。当rpc client需要连接某个rpc server的时候,前者只知道 <br>

  <br>

远程程序号和远程程序版本号,于是它向目标主机的知名端口111提供的服务 <br>

  <br>

查询拥有相应远程程序号和远程程序版本号的rpc server当前所注册使用的端口 <br>

  <br>

号,由portmap/rpcbind向rpc client提供这个端口值,当rpc client获得 <br>

  <br>

rpc server所使用的端口值后就可以直接与rpc server通信了。所以,如果上面 <br>

  <br>

rdictd二次启动后用rpcinfo查看,会发现port值改变。从上面简单介绍的理论 <br>

  <br>

中应该明白,rpc server必须向portmap注册,所以如果: <br>

  <br>

  <br>

  <br>

[root@ /home/scz/src]> /etc/rc.d/init.d/portmap status <br>

  <br>

  <br>

portmap (pid 539) is running... <br>

  <br>

[root@ /home/scz/src]> /etc/rc.d/init.d/portmap stop <br>

  <br>

Stopping portmap services: <br>

  <br>

       [  OK  ] <br>

  <br>

[root@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

[scz@ /home/scz/src]> /usr/sbin/rpcinfo -p localhost <br>

  <br>

rpcinfo: can't contact portmapper: RPC: Remote system error - Connection <br>

  <br>

 refused <br>

  <br>

[scz@ /home/scz/src]> ./rdictd <br>

  <br>

Cannot register service: RPC: Unable to receive; errno = Connection <br>

  <br>

  <br>

refused <br>

  <br>

  <br>

  <br>

unable to register (RDICTPROG, RDICTVERS, udp). <br>

  <br>

[scz@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

现在你是否对rpc程序执行中的错误提示有了进一步了解呢。如果答案肯定, <br>

  <br>

那我很高兴。注意这里,如果当初没有修改过rdict_svc.c,最后的错误提示 <br>

  <br>

会让你非常恼火,因为没有回车换行。 <br>

  <br>

  <br>

  <br>

通过netconf设置portmap服务在系统启动的时候就开始。如果要临时测试, <br>

  <br>

就是上面那个办法。有的系统是在/etc/inetd.conf中提供rpcbind服务, <br>

  <br>

  <br>

也是111端口,必须注意到这一点。 <br>

  <br>

  <br>

  <br>

我这里居然没有rpcinfo的man手册,活见鬼,所以那些命令行选项什么意思 <br>

  <br>

我也不清楚,只能挑我大概知道的给出例子,如果你明白就赶快贴出来好了, <br>

  <br>

solaris下应该有相应的man手册吧。 <br>

  <br>

  <br>

  <br>

下面我们来看看rpcinfo的其他命令行选项: <br>

  <br>

  <br>

  <br>

[scz@ /home/scz/src]> hostname <br>

  <br>

higgs.*.*.* <br>

  <br>

[scz@ /home/scz/src]> /usr/sbin/rpcinfo -b 805898569 1 <br>

  <br>

  <br>

192.168.67.108 server.*.*.* <br>

  <br>

^C <br>

  <br>

[scz@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

-b选项似乎是在局域网上探测指定rpc server的存在??? <br>

  <br>

  <br>

  <br>

[root@ /home/scz/src]> rpcinfo -d 100000 2 <br>

  <br>

[root@ /home/scz/src]> rpcinfo -p localhost <br>

  <br>

No remote programs registered. <br>

  <br>

[root@ /home/scz/src]> /etc/rc.d/init.d/portmap status <br>

  <br>

portmap (pid 740) is running... <br>

  <br>

  <br>

[root@ /home/scz/src]> ./rdictd & <br>

  <br>

[root@ /home/scz/src]> jobs <br>

  <br>

[1]+  Running                 ./rdictd & <br>

  <br>

[root@ /home/scz/src]> rpcinfo -p localhost <br>

  <br>

   program vers proto   port <br>

  <br>

 805898569    1   udp    966 <br>

  <br>

 805898569    1   tcp    968 <br>

  <br>

[root@ /home/scz/src]> kill %1 <br>

  <br>

[1]+  Terminated              ./rdictd <br>

  <br>

[root@ /home/scz/src]> jobs <br>

  <br>

[root@ /home/scz/src]> rpcinfo -p localhost <br>

  <br>

  <br>

   program vers proto   port <br>

  <br>

 805898569    1   udp    966 <br>

  <br>

 805898569    1   tcp    968 <br>

  <br>

[root@ /home/scz/src]> rpcinfo -d 805898569 1 <br>

  <br>

[root@ /home/scz/src]> rpcinfo -p localhost <br>

  <br>

No remote programs registered. <br>

  <br>

[root@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

-d选项看来是反注册用的。注意到rdictd虽然被杀,但动态端口注册信息依 <br>

  <br>

旧存在,需要额外地用rpcinfo -d反注册一下,同样先反注册并不会导致 <br>

  <br>

rdictd终止,这两者没有捆绑。rpcbind被反注册掉不影响什么,至少目前 <br>

  <br>

  <br>

测试结果如此,也许rpcbind本身注册一次仅仅是保持某种一致性,因为它 <br>

  <br>

使用的是固定的周知端口111,根本不用注册的。 <br>

  <br>

  <br>

  <br>

[scz@ /home/scz/src]> ./rdictd & <br>

  <br>

[1] 798 <br>

  <br>

[scz@ /home/scz/src]> rpcinfo -p localhost <br>

  <br>

   program vers proto   port <br>

  <br>

 805898569    1   udp   1043 <br>

  <br>

 805898569    1   tcp   1054 <br>

  <br>

[scz@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

  <br>

[scz@ /home/scz/src]> hostname <br>

  <br>

higgs.*.*.* <br>

  <br>

[scz@ /home/scz/src]> /usr/sbin/rpcinfo -t server 805898569 <br>

  <br>

program 805898569 version 1 ready and waiting <br>

  <br>

[scz@ /home/scz/src]> /usr/sbin/rpcinfo -n 1043 -u server 805898569 1 <br>

  <br>

program 805898569 version 1 ready and waiting <br>

  <br>

[scz@ /home/scz/src]> <br>

  <br>

  <br>

  <br>

简单的小结: <br>

  <br>

  <br>

  <br>

    . 构建一个解决问题的常规程序。 <br>

  <br>

  <br>

    . 根据某种原则划分开,其中一部分是准备迁移到远程主机上作为远 <br>

  <br>

      程过程调用的。 <br>

  <br>

    . 编写rpcgen规格说明文件 <br>

  <br>

    . 运行rpcgen <br>

  <br>

    . 为rpc client和rpc server编写各自的stub接口例程 <br>

  <br>

    . 编译连接rpc client和rpc server <br>

  <br>

  <br>

  <br>

rpcgen虽然解决了很多问题,但并非一定要使用rpcgen进行rpc编程。 <br>

  <br>

尤其当一个rpc server是另外一个rpc server的rpc client的时候, <br>

  <br>

rpcgen的局限性就暴露出来了。 <br>

  <br>

  <br>

  <br>



后记: <br>

  <br>

  <br>

  <br>

    正好要做点和RPC/NFS有关的协议分析,于是就 <br>

  <br>

    把上面那本书重新翻出来,照猫画老虎地先测试 <br>

  <br>

    一个完整的RPC程序,给自己一点信心也给大家 <br>

  <br>

    一个免除重复劳动的便宜捡。有任何技术性问题, <br>

  <br>

    可以< mailto: cloudsky@263.net >,反正我什么 <br>

  <br>

    都不知道,你要教训我正好嘛,:-) <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="15.htm">上一层</a>][<a href="560.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -