| RPC/XDR/NFS系列之----RPC编程初战 |
热 |
| RPC/XDR/NFS系列之----RPC编程初战 |
|
|
|
作者:佚名 文章来源:不详 点击数: 更新时间:2006-12-4 16:10:45  |
原作:Douglas E. Comer & David L. Stevens << Internetworking With TCP/IP Vol III >> 整理修改:scz < mailto: cloudsky@263.net > 概述: 所有关于原理的部分以后再贴,这里直奔程序设 计而去。文章中的程序就是书中的程序,但原文 针对Xinu系统来的,要不就针对Sun RPC来的, 我这里只有Redhat,改动是一定的,在后面的小 节里我会指出改动过的地方。完整地演习过这个 系列,你就不在畏惧RPC。计划在后面的灌水中 讲述RPC远程过程调用发生缓冲区溢出的原理, 不过仅仅是计划,要看时间是否允许。 下面的程序完成一个字典的常规维护工作,代码 很简单,让我们开始。 测试: RedHat6.0测试,如果在solaris下,应该更容易实现, 因为Sun RPC是事实上的标准,rpcgen是Sun自己的工 具嘛。 目录: ★ 构建一个解决问题的常规应用程序 ★ 将该常规程序划分成两部分 ★ 创建一个rpcgen规格说明 ★ 运行rpcgen ★ rpcgen产生的.h文件 ★ rpcgen产生的XDR转换文件 ★ rpcgen产生的client代码 ★ rpcgen产生的server代码 ★ 编写stub接口过程 ★ 编译链接client程序 ★ 编译链接server程序 ★ 启动服务器执行客户机 ★ 分离服务器和客户机 ★ rpcinfo的使用以及portmap原理简介(重要) ★ RPC程序编译开关 ★ RPC编程小结 ★ 构建一个解决问题的常规应用程序 下面这个程序很简单,实现一个字典的简单维护工作,不多解释了。 /* dict.c -- main, initw, nextin, insertw, deletew, lookupw */ #include #include #include #include #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 */ intnwords = 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; intwordlen;/* 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 */ [scz@ /home/scz/src]> cat > dict.c [scz@ /home/scz/src]> gcc -Wall -O3 -o dict dict.c [scz@ /home/scz/src]> strip dict [scz@ /home/scz/src]> ./dict Please input: II < -- -- -- 原来的例子,怀疑作者并没有实际测试过,这里有点问题 Dictionary initialized to empty. i word1 word1 inserted. i word2 word2 inserted. i word3 word3 inserted. l word2 word2 was found. d word2 word2 deleted. l word2 word2 was not found. qq < -- -- -- 问题同上,请仔细阅读nextin()函数的代码 Program quits. [scz@ /home/scz/src]> 现在我们拥有了一个解决的的常规程序,该程序不是分布式的。 ★ 将该常规程序划分成两部分 下图是常规程序的函数关系图。 main ---- nextin | | ---- insertw | | ---- initw | | ---- deletew | | ---- lookupw nextin用于读取下一个输入行,需要访问标准输入stdin,应该和main函数放在一起。 原则:执行I/O或者访问了文件句柄的过程不能轻易转移到远程主机上。 lookupw需要访问全部单词数据库,如果执行lookupw的主机和字典所在主机不是同一主机, 则对lookupw的RPC调用就必须将整个字典作为参数传递,这是不可取的。 原则:执行过程的主机应该和过程执行中需访问数据所在主机一致。 于是可以按照如下图示划分远程过程: client端server端 发起RPC远程过程调用端 响应RPC远程过程调用端 ------------------------------------------------- || RPC调用| | |main -|----------------| initwlookupw| ||| 字典数据结构| | nextin || insertwdeletew| ||| | ------------------------------------------------- /* dict1.c -- main, nextin */ #include #include #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; intwordlen;/* 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 ); } &nbs[1] [2] [3] [4] [5] 下一页
|
| 文章录入:bolang 责任编辑:bolang |
|
上一篇文章: 关于SLKM隐含目录的bug 下一篇文章: CGI 安全问题 |
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |