Linux 下C使用XML传递消息(字符串)

来源:互联网 发布:北京知镜科技有限公司 编辑:程序博客网 时间:2024/05/01 06:00

在linux下经常要进行socket通信,而数据流多采用目前流行的xml格式,这就会有两个用的比较多的功能:
1、接收端将收到的字符串转换成xml格式的数据;
2、发送端将xml格式的数据转换成字符串发送。

运用libxml2组件进行上述操作实际上是xmlDocPtr和xmlChar两种类型之间的转换。

1. xmlDocPtr -> xmlChar
xmlDocPtr doc;
xmlChar *xmlbuff;
int buffersize;
xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
2. xmlChar -> xmlDocPtr
xmlDocPtr doc;
char * cData;
doc = xmlParseMemory(docname, strlen(cData)+1);
怎样把xmlChar转换成char就无须多讲了,直接用(char*)强行转换也行。

(以上,转自http://hi.baidu.com/dante300/blog/item/b0962f51e472261d0cf3e3ad.html)


下面的例子,srv端等待6601端口的数据,并使用XML解析,取得其中的name和age项,并打印到终端

client端读取一个XML文件,并把读取的数据转换为字符串,向服务端的端口发送

[cpp] view plaincopy
  1. /*srv.c By ksir in 2011-10-14*/  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <string.h>  
  5. #include <ctype.h>  
  6. #include <sys/socket.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #include <libxml/parser.h>  
  10. #include <libxml/xmlmemory.h>  
  11.   
  12. #define MAXLINE 80  
  13. int port = 6601;        /*Port of socket*/  
  14.   
  15. /*parse XML and show content of 'name','age'*/  
  16. int parseXML(xmlDocPtr tmpdoc)  
  17. {  
  18.     //printf("This is in parseXML\n");  
  19.     xmlNodePtr curNode; /*Keep node of the xml tree*/  
  20.     xmlChar *szKey;  
  21.   
  22.     /*Get the root Node from tmpdoc*/  
  23.     curNode = xmlDocGetRootElement(tmpdoc);  
  24.     /*check the content of the document*/  
  25.     if (NULL == curNode)  
  26.     {  
  27.         xmlFreeDoc(tmpdoc);  
  28.         return -3;  
  29.     }  
  30.   
  31.     /*Check the type of the root element*/  
  32.     if(xmlStrcmp(curNode->name,BAD_CAST"n"))  
  33.     {  
  34.         printf("Document of the wrong type");  
  35.         xmlFreeDoc(tmpdoc);  
  36.         return -4;  
  37.     }  
  38.     curNode = curNode->xmlChildrenNode;  
  39.     xmlNodePtr propNpdePtr =curNode;  
  40.     while (curNode != NULL)  
  41.     {  
  42.         /*compare element nodes,show the content*/  
  43.         if( !(xmlStrcmp(curNode->name,(const xmlChar *)"name")))  
  44.         {  
  45.             szKey = xmlNodeGetContent(curNode);  
  46.             printf("name:%s\n",szKey);  
  47.             xmlFree(szKey);  
  48.         }  
  49.         else if( !(xmlStrcmp(curNode->name,(const xmlChar *)"age")))  
  50.         {  
  51.             printf("Age:%s\n",xmlNodeGetContent(curNode));  
  52.         }  
  53.         /*traverse*/  
  54.         curNode = curNode->next;  
  55.     }  
  56.     xmlFreeDoc(tmpdoc);  
  57.     return 0;  
  58. }  
  59.   
  60. int main(void)  
  61. {  
  62.     struct sockaddr_in sin;  
  63.     struct sockaddr_in rin;  
  64.     int sock_fd;  
  65.     int address_size;  
  66.     char buf[MAXLINE];  
  67.     char str[INET_ADDRSTRLEN];  
  68.     int len;  
  69.     int n;  
  70.   
  71.     xmlDocPtr doc;  
  72.   
  73.     bzero(&sin, sizeof(sin));  
  74.     sin.sin_family = AF_INET;  
  75.     sin.sin_addr.s_addr = INADDR_ANY;  
  76.     sin.sin_port = htons(port);  
  77.   
  78.   
  79.     sock_fd = socket(AF_INET, SOCK_DGRAM, 0);  
  80.     if (-1 == sock_fd)  
  81.     {  
  82.         perror("call to socket");  
  83.         exit(1);  
  84.     }  
  85.     n = bind(sock_fd, (struct sockaddr *)&sin, sizeof(sin));  
  86.     if (-1 == n)  
  87.     {  
  88.         perror("call to bind");  
  89.         exit(1);  
  90.     }  
  91.   
  92.     while(1)  
  93.     {  
  94.         address_size = sizeof(rin);  
  95.         n = recvfrom(sock_fd,buf,MAXLINE,0,(struct sockaddr *)&rin,  
  96.                 &address_size);  
  97.         if (-1 == n)  
  98.         {  
  99.             perror("call to recvfrom.\n");  
  100.             exit(1);  
  101.         }  
  102.     //  printf("you ip is %s at port %d:%s\n",  
  103.     //          inet_ntop(AF_INET, &rin.sin_addr,str,sizeof(str)),  
  104.     //          ntohs(rin.sin_port),(char *)buf);  
  105.   
  106.         /*transfer buf to xml*/  
  107.         doc = xmlParseMemory((char *)buf,strlen(buf)+1);  
  108.         if (NULL == doc)  
  109.         {  
  110.             printf("xmlParseMemory fail\n");  
  111.             return -2;  
  112.         }  
  113.         parseXML(doc);  
  114.     }  
  115.     return 0;  
  116. }  

客户端代码:

[cpp] view plaincopy
  1. /*Client.c by ksir in 2011-10-14*/  
  2.   
  3. #include<stdio.h>  
  4. #include<string.h>  
  5. #include<stdlib.h>  
  6. #include<sys/types.h>  
  7. #include<unistd.h>  
  8. #include<sys/socket.h>  
  9. #include<linux/in.h>  
  10. #include <libxml/parser.h>  
  11. #include <libxml/xmlmemory.h>  
  12.   
  13.   
  14. int main(int argc,char *argv[])  
  15. {  
  16.     if(argc<2){  
  17.         printf("Please input a file !\n");  
  18.         exit(0);  
  19.     }  
  20.     int sock;  
  21.     struct sockaddr_in toAddr;  
  22.     struct sockaddr_in fromAddr;  
  23.       
  24.     unsigned int fromLen;  
  25.     char recvBuffer[128];  
  26.     sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);  
  27.     if(sock<0){  
  28.         printf("Sock failed!\n");  
  29.         exit(1);  
  30.     }     
  31.       
  32.     memset(&toAddr,0,sizeof(toAddr));  
  33.       
  34.     toAddr.sin_family=AF_INET;  
  35.     toAddr.sin_addr.s_addr=inet_addr("10.11.1.88");  
  36.     toAddr.sin_port=htons(6601);  
  37.       
  38.     /*Get the xmlfile and parse into string*/  
  39.     xmlDocPtr doc;      /*file descriptor of the xml*/  
  40.     xmlChar *xmlbuf;  
  41.     char *szDocName;  
  42.     int buffersize;  
  43.   
  44.     szDocName = argv[1];  
  45.   
  46.     /*Open with GB2312*/  
  47.     doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER);  
  48.     xmlDocDumpFormatMemory(doc, &xmlbuf, &buffersize, 1);  
  49.     printf((char *) xmlbuf);  
  50.   
  51.     while(1)  
  52.     {  
  53.         sleep(1);  
  54.   
  55.         if(sendto(sock,xmlbuf,strlen(xmlbuf)+1,0,(struct sockaddr *)&toAddr,sizeof(toAddr)) == -1){  
  56.             printf("Sendto failed!\n");  
  57.             exit(2);  
  58.             }  
  59.       
  60.     printf("OK!\n");  
  61.     }  
  62.     close(sock);  
  63. }  
使用的XML文件:

[html] view plaincopy
  1. <n>  
  2.     <name>  
  3.     ksir  
  4.     </name>  
  5.     <age>  
  6.     18  
  7.     </age>  
  8. </n>  

使用libxml2库的.c文件的编译:

gcc -o srv ser.c -I /usr/include/libxml2/ -L /usr/local/lib  -lxml2

LIBXML2的学习地址:http://www.xmlsoft.org/html/libxml-tree.html

原创粉丝点击