1. 程式人生 > >Linux RPC中XDR 外部數據編碼實例

Linux RPC中XDR 外部數據編碼實例

urn upd 外部 模式 字符 structure 常用 計算 sin

網上找了很多XDR編碼的內容,但是大多都是介紹相關的,很少有編程實例。因為分布式的課程學習了XDR外部數據編碼,並應用在了RPC遠程過程調用的實現中。本篇博客先暫時描述XDR相關,下一篇將介紹Socket通信。

這一篇博客介紹了XDR的內部實現 http://blog.csdn.net/chdhust/article/details/9004496 ,需要了解實現的可以參考一下。

XDR的主要作用就是在不同進程間傳遞消息參數時,避免因為計算機平臺的不一致而導致數據傳送接收異常。它可以對消息參數按照一定的順序編碼,放在一個數據包裏(通常是在內存中申請一個一定大小的字符串緩沖區),然後把這個數據包發送給其他平臺,然後在按照之前編碼的順序依次解碼,並可以獲得原來的消息參數。

這一篇博客簡單的描述了一個XDR編碼實例 http://blog.csdn.net/seulww/article/details/23093913

環境要求:

  Linux 操作系統

  rpc/xdr.h

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<malloc.h>
 4 #include<rpc/xdr.h>
 5 #include<cstring>
 6 using namespace std;
 7 
 8 char* func()
 9 {
10     char *res = (char
*)malloc(sizeof(char)*1024); 11 sprintf(res,"nihao,你好 \n"); 12 return res; 13 } 14 15 int main(int argc,char* argv[]) 16 { 17 printf("begin...\n"); 18 19 short age = 34; 20 char sex = M; 21 double weights = 66.66; 22 char name[20]; 23 strcpy(name,"LJ"); 24 char *p = name;
25 26 27 XDR xdr; 28 char buff[120]; 29 30 xdrmem_create(&xdr,buff,120,XDR_ENCODE); 31 xdr_string(&xdr,&p,sizeof p); 32 xdr_short(&xdr,&age); 33 xdr_char(&xdr,&sex); 34 xdr_double(&xdr,&weights); 35 36 xdrmem_create(&xdr,buff,120,XDR_DECODE); 37 char name2[20]; 38 char *p2 = name2; 39 cout<<strlen(p2)<<endl; 40 xdr_string(&xdr,&p2,sizeof p2); 41 short age2; 42 xdr_short(&xdr,&age2); 43 char sex2; 44 xdr_char(&xdr,&sex2); 45 double weights2; 46 xdr_double(&xdr,&weights2); 47 48 printf("%s %d %c %lf\n",p2,age2,sex2,weights2); 49 50 memset(buff,0,sizeof buff); 51 xdrmem_create(&xdr,buff,sizeof buff,XDR_ENCODE); 52 char *p4 = (char *)malloc(sizeof(char)*1024); 53 p4 = func(); 54 printf("p4 = %s\n",p4); 55 printf("sizeof p4 = %d\n",(int)(sizeof p4)); 56 xdr_string(&xdr,&p4,1024); 57 58 xdrmem_create(&xdr,buff,sizeof buff,XDR_DECODE); 59 char str2[1024]; 60 char *p5 = str2; 61 xdr_string(&xdr,&p5,1024); 62 63 printf("str2 = %s\n",str2); 64 65 return 0; 66 } 67 68 /* FILE* pFile = fopen("in.txt","ab+"); 69 XDR xdr; 70 xdrstdio_create(&xdr,pFile,XDR_ENCODE); 71 int n = 299; 72 xdr_int(&xdr,&n); 73 xdr_destroy(&xdr); 74 fclose(pFile); 75 */

詳解:

  XDR xdr;  //  定義一個xdr對象

  xdrmem_create(&xdr,buff,120,XDR_ENCODE);  //  創建編碼模式,buff是自定義的緩沖區,存放參數,120其實是buff的大小,XDR_ENCODE是編碼,相應的XDR_DECODE解碼

  xdr_int(&xdr,&n);  //  根據參數類型進行編碼  xdr_type(&xdr,&type);

      需要註意的是,字符串的編碼要用 xdr_string,並且引用&的參數必須是變量,而不能是字符串的數組名,這是C語言的規則,數組名雖然是數組的首地址指針,但是不是變量,不能引用&。

  xdrmem_create(&xdr,buff,120,XDR_DECODE);  //  解碼過程和編碼過程放過來,具體參考代碼

註意代碼中綠色被註釋部分:

  是xdr文件編碼的方式,而不是使用內存中的緩沖區來存儲信息,使用方式類似的。

列舉一些常用的編碼函數(來自Linux中xdr.h):

/* XDR using memory buffers */
extern void xdrmem_create (XDR *__xdrs, const caddr_t __addr,
               u_int __size, enum xdr_op __xop) __THROW;

/* XDR using stdio library */
extern void xdrstdio_create (XDR *__xdrs, FILE *__file, enum xdr_op __xop)
     __THROW;

/*
 * These are the "generic" xdr routines.
 * None of these can have const applied because it‘s not possible to
 * know whether the call is a read or a write to the passed parameter
 * also, the XDR structure is always updated by some of these calls.
 */
extern bool_t xdr_void (void) __THROW;
extern bool_t xdr_short (XDR *__xdrs, short *__sp) __THROW;
extern bool_t xdr_u_short (XDR *__xdrs, u_short *__usp) __THROW;
extern bool_t xdr_int (XDR *__xdrs, int *__ip) __THROW;
extern bool_t xdr_u_int (XDR *__xdrs, u_int *__up) __THROW;
extern bool_t xdr_long (XDR *__xdrs, long *__lp) __THROW;
extern bool_t xdr_u_long (XDR *__xdrs, u_long *__ulp) __THROW;
extern bool_t xdr_hyper (XDR *__xdrs, quad_t *__llp) __THROW;
extern bool_t xdr_u_hyper (XDR *__xdrs, u_quad_t *__ullp) __THROW;
extern bool_t xdr_longlong_t (XDR *__xdrs, quad_t *__llp) __THROW;
extern bool_t xdr_u_longlong_t (XDR *__xdrs, u_quad_t *__ullp) __THROW;
extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip) __THROW;
extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up) __THROW;
extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip) __THROW;
extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up) __THROW;
extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip) __THROW;
extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up) __THROW;
extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip) __THROW;
extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up) __THROW;
extern bool_t xdr_quad_t (XDR *__xdrs, quad_t *__ip) __THROW;
extern bool_t xdr_u_quad_t (XDR *__xdrs, u_quad_t *__up) __THROW;
extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp) __THROW;
extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep) __THROW;
extern bool_t xdr_array (XDR * _xdrs, caddr_t *__addrp, u_int *__sizep,
             u_int __maxsize, u_int __elsize, xdrproc_t __elproc)
     __THROW;
extern bool_t xdr_bytes (XDR *__xdrs, char **__cpp, u_int *__sizep,
             u_int __maxsize) __THROW;
extern bool_t xdr_opaque (XDR *__xdrs, caddr_t __cp, u_int __cnt) __THROW;
extern bool_t xdr_string (XDR *__xdrs, char **__cpp, u_int __maxsize) __THROW;
extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
             const struct xdr_discrim *__choices,
             xdrproc_t __dfault) __THROW;
extern bool_t xdr_char (XDR *__xdrs, char *__cp) __THROW;
extern bool_t xdr_u_char (XDR *__xdrs, u_char *__cp) __THROW;
extern bool_t xdr_vector (XDR *__xdrs, char *__basep, u_int __nelem,
              u_int __elemsize, xdrproc_t __xdr_elem) __THROW;
extern bool_t xdr_float (XDR *__xdrs, float *__fp) __THROW;
extern bool_t xdr_double (XDR *__xdrs, double *__dp) __THROW;
extern bool_t xdr_reference (XDR *__xdrs, caddr_t *__xpp, u_int __size,
                 xdrproc_t __proc) __THROW;
extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
               u_int __obj_size, xdrproc_t __xdr_obj) __THROW;
extern bool_t xdr_wrapstring (XDR *__xdrs, char **__cpp) __THROW;
extern u_long xdr_sizeof (xdrproc_t, void *) __THROW;

Linux RPC中XDR 外部數據編碼實例