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

来源:互联网 发布:ubuntu cuda test 编辑:程序博客网 时间:2024/04/27 13:46

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

客户端代码:

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

[html] view plaincopyprint?
  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

0 0
原创粉丝点击