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

📄 567.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="568.htm">下一篇</a>]
<hr><p align="left"><small>发信人: cloudsky (小四), 信区: Security <br>

标  题: RPC/XDR/NFS系列之----外部数据表示 <br>

发信站: 武汉白云黄鹤站 (Wed Feb 23 17:30:45 2000), 站内信件 <br>

现在让我们回头来看看<<RPC/XDR/NFS系列之----RPC编程初战(1)>>中 <br>

"rpcgen产生的XDR转换文件"小节里的那个函数 <br>

bool_t xdr_example ( XDR * xdrs, example * objp ) <br>

{ <br>

    register long * buf; <br>

    if ( !xdr_int( xdrs, &objp->exfield1 ) ) <br>

    { <br>

        return FALSE;  /* 转换失败返回FALSE */ <br>

    } <br>

    if ( !xdr_char( xdrs, &objp->exfield2 ) ) <br>

    { <br>

        return FALSE; <br>

    } <br>

    return TRUE;  /* 转换成功则返回TRUE */ <br>

} <br>

struct example <br>

{ <br>

    int  exfield1; <br>

    char exfield2; <br>

}; <br>

}; <br>

显然,XDR处理C的struct的时候就是简单地依次处理每个成员,具体到这里 <br>

就是分别调用了xdr_int和xdr_char转换例程,很好理解,是不是? <br>

★ XDR库中的转换例程(Redhat) <br>

可以查看/usr/include/rpc/xdr.h,找到所有可用的XDR转换例程 <br>

/* <br>

 * These are the "generic" xdr routines. <br>

 * None of these can have const applied because it's not possible to <br>

 * know whether the call is a read or a write to the passed parameter <br>

 * also, the XDR structure is always updated by some of these calls. <br>

 */ <br>

extern bool_t xdr_void __P ((void)); <br>

extern bool_t xdr_short __P ((XDR *__xdrs, short *__sp)); <br>

extern bool_t xdr_u_short __P ((XDR *__xdrs, u_short *__usp)); <br>

extern bool_t xdr_int __P ((XDR *__xdrs, int *__ip)); <br>

extern bool_t xdr_u_int __P ((XDR *__xdrs, u_int *__up)); <br>

extern bool_t xdr_long __P ((XDR *__xdrs, long *__lp)); <br>

extern bool_t xdr_u_long __P ((XDR *__xdrs, u_long *__ulp)); <br>

extern bool_t xdr_hyper __P ((XDR *__xdrs, quad_t *__llp)); <br>

extern bool_t xdr_u_hyper __P ((XDR *__xdrs, u_quad_t *__ullp)); <br>

extern bool_t xdr_longlong_t __P ((XDR *__xdrs, quad_t *__llp)); <br>

extern bool_t xdr_u_longlong_t __P ((XDR *__xdrs, u_quad_t *__ullp)); <br>

extern bool_t xdr_int8_t __P ((XDR *__xdrs, int8_t *__ip)); <br>



extern bool_t xdr_uint8_t __P ((XDR *__xdrs, uint8_t *__up)); <br>

extern bool_t xdr_int16_t __P ((XDR *__xdrs, int16_t *__ip)); <br>

extern bool_t xdr_uint16_t __P ((XDR *__xdrs, uint16_t *__up)); <br>

extern bool_t xdr_int32_t __P ((XDR *__xdrs, int32_t *__ip)); <br>

extern bool_t xdr_uint32_t __P ((XDR *__xdrs, uint32_t *__up)); <br>

extern bool_t xdr_int64_t __P ((XDR *__xdrs, int64_t *__ip)); <br>

extern bool_t xdr_uint64_t __P ((XDR *__xdrs, uint64_t *__up)); <br>

extern bool_t xdr_bool __P ((XDR *__xdrs, bool_t *__bp)); <br>

extern bool_t xdr_enum __P ((XDR *__xdrs, enum_t *__ep)); <br>

extern bool_t xdr_array __P ((XDR * _xdrs, caddr_t *__addrp, u_int *__sizep, <br>

  <br>

                              u_int __maxsize, u_int __elsize, <br>

                              xdrproc_t __elproc)); <br>

extern bool_t xdr_bytes __P ((XDR *__xdrs, char **__cpp, u_int *__sizep, <br>

                              u_int __maxsize)); <br>

extern bool_t xdr_opaque __P ((XDR *__xdrs, caddr_t __cp, u_int __cnt)); <br>

extern bool_t xdr_string __P ((XDR *__xdrs, char **__cpp, u_int __maxsize)); <br>

  <br>

extern bool_t xdr_union __P ((XDR *__xdrs, enum_t *__dscmp, char *__unp, <br>

                              __const struct xdr_discrim *__choices, <br>

                              xdrproc_t dfault)); <br>

extern bool_t xdr_char __P ((XDR *__xdrs, char *__cp)); <br>



extern bool_t xdr_u_char __P ((XDR *__xdrs, u_char *__cp)); <br>

extern bool_t xdr_vector __P ((XDR *__xdrs, char *__basep, u_int __nelem, <br>

                               u_int __elemsize, xdrproc_t __xdr_elem)); <br>

extern bool_t xdr_float __P ((XDR *__xdrs, float *__fp)); <br>

extern bool_t xdr_double __P ((XDR *__xdrs, double *__dp)); <br>

extern bool_t xdr_reference __P ((XDR *__xdrs, caddr_t *__xpp, u_int __size, <br>

  <br>

                                  xdrproc_t __proc)); <br>

extern bool_t xdr_pointer __P ((XDR *__xdrs, char **__objpp, <br>

                                u_int __obj_size, xdrproc_t __xdr_obj)); <br>

extern bool_t xdr_wrapstring __P ((XDR *__xdrs, char **__cpp)); <br>

extern u_long xdr_sizeof __P ((xdrproc_t, void *)); <br>

为了形成一个RPC报文,应用程序要为报文中的每个数据项调用XDR转换例程。应用程序 <br>

  <br>

发送最终生成的XDR流,接收方必须颠倒整个过程。 <br>

接收方调用xdrmem_create初始化用于存放XDR流的内存缓冲区,将接收到的报文放入该 <br>

  <br>

缓冲区。XDR流自己记录了转换方向(应该是保存在XDR流首部中),以确定是编码还是解 <br>

码, <br>

xdrmem_create函数的第三个参数指明了XDR例程的转换方向。 <br>

xdrmem_create( xdrs, buf, BUFSIZE, XDR_DECODE ); <br>

一旦接收方已经建立用于解码的XDR流,就可以调用转换例程从XDR流中获得相应类型的 <br>



数 <br>

据,并将该数据转换成本地数据表示: <br>

int i;                /* 使用本地表示的整数 */ <br>

... ...               /* XDR流已经初始化成解码 */ <br>

xdr_int( xdrs, &i );  /* 从XDR流中提取整数 */ <br>

这里有别于BSD的htons和ntohs转换例程,XDR转换例程不需要单独指定转换方向, <br>

转换方向是在创建XDR流时指定的,XDR转换例程会检查XDR流中保存的这个转换方向。 <br>

★ xdrstdio_create函数 <br>

使用xdrmem_create创建的XDR流允许应用程序向网络发送数据前把大量数据转换成 <br>

外部数据表示。各个数据项逗被转换并放入缓冲区后,应用程序将调用一个象write <br>

这样的I/O函数以便在一个TCP/IP连接上将其发送出去。 <br>

可以让XDR转换例程每次转换完毕一个数据项就自动发送出去。为此需要介绍 <br>

xdrstdio_create函数。 <br>

在/usr/include/rpc/xdr.h中有如下定义: <br>

/* XDR using stdio library */ <br>

extern void xdrstdio_create __P ((XDR *__xdrs, FILE *__file, enum xdr_op __x <br>

op)) <br>

; <br>

首先建立一个标准的socket,然后用fdopen获得该socket的I/O流表示,然后调用 <br>

xdrstdio_create函数初始化一个XDR流。针对如此创建的XDR流调用XDR转换例程, <br>

会自动完成一个带缓冲的read/write操作。应用程序可以调用Unix标准I/O函数 <br>

对I/O流操作,比如仅仅转换了几个字节就希望输出,可以调用fflush函数。 <br>



★ xdrrec_create函数,XDR流与UDP socket <br>

XDR流与TCP socket可以很好结合,因为二者都使用了抽象的流概念。为了和UDP socke <br>

t <br>

结合,创建XDR流时需要调用xdrrec_create函数。 <br>

在/usr/include/rpc/xdr.h中有如下定义: <br>

/* XDR pseudo records for tcp */ <br>

extern void xdrrec_create __P ((XDR *__xdrs, u_int __sendsize, <br>

                                u_int __recvsize, caddr_t __tcp_handle, <br>

                                int (*__readit) (char *, char *, int), <br>

                                int (*__writeit) (char *, char *, int))); <br>

/* make end of xdr record */ <br>

extern bool_t xdrrec_endofrecord __P ((XDR *__xdrs, bool_t __sendnow)); <br>

/* move to beginning of next record */ <br>

extern bool_t xdrrec_skiprecord __P ((XDR *__xdrs)); <br>

/* true if no more input */ <br>

extern bool_t xdrrec_eof __P ((XDR *__xdrs)); <br>

注意到xdrrec_create函数有两个形参readit和writeit。每次调用XDR转换例程将本地 <br>

表示转换成外部表示时,转换例程将检查缓冲区是否还有空间容纳新数据,如果缓冲区 <br>

  <br>

满,转换例程调用writeit发送缓冲区已有内容,为新数据腾出空间。类似,每次调用 <br>

XDR转换例程将外部表示转换成本地表示时,转换例程将检查缓冲区是否含有数据,如 <br>

果缓冲区空,转换例程调用readit获得更多数据到缓冲区。 <br>



为使XDR流与UDP socket结合,调用xdrrec_create创建一个面向记录的XDR流,readit <br>

/writeit对应read/write或者recv/send。应用程序填满缓冲区时,转换例程调用send <br>

用单个UDP数据报发送缓冲区内容。应用程序调用转换例程获取数据时,转换例程调用 <br>

recv获取下一个入UDP数据报,并放入缓冲区中。 <br>

面向记录的XDR流上可以使用xdrrec_endofrecord、xdrrec_skiprecord、xdrrec_eof <br>

函数。 <br>

★ 相关RFC以及参考资料 <br>

RFC 1014 <<XDR: External Data Representation Standard>> <br>

它是Sun Microsystems 公司定义的XDR编码和转换例程。 <br>

RFC 1832 <br>

新版本,这是一个建议标准。 <br>

至于更多的信息应该参考<<solaris网络编程指南>>,我曾经有全套 <br>

solaris的书籍来着,可惜北上前送给同学,太多太重啦,sigh <br>

Douglas E. Comer & David L. Stevens <br>

<< Internetworking With TCP/IP Vol III >> <br>

W.Richard Stevens <br>

<< TCP/IP Illustrated Volume I >> <br>

我的建议是不要看中文翻译版,而是直接看英文原版,许多地方翻译走样。 <br>

scz < mailto: cloudsky@263.net > <br>

2000.02.21 13:59 (待续) <br>

-- <br>

            我问飘逝的风:来迟了? <br>



            风感慨:是的,他们已经宣战。 <br>

            我问苏醒的大地:还有希望么? <br>

            大地揉了揉眼睛:还有,还有无数代的少年。 <br>

            我问长空中的英魂:你们相信? <br>

            英魂带着笑意离去:相信,希望还在。 <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="15.htm">上一层</a>][<a href="568.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 + -