Chinaunix首页 | 论坛 | 博客
  • 博客访问: 304960
  • 博文数量: 68
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 706
  • 用 户 组: 普通用户
  • 注册时间: 2015-08-13 14:58
文章分类

全部博文(68)

文章存档

2021年(4)

2020年(6)

2018年(5)

2017年(13)

2016年(8)

2015年(32)

我的朋友

分类: C/C++

2015-10-22 13:35:38

在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文件,并把读取的数据转换为字符串,向服务端的端口发送


点击(此处)折叠或打开

  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. }

客户端

/*Client.c by ksir in 2011-10-14*/

#include
#include
#include
#include
#include
#include
#include
#include
#include


int main(int argc,char *argv[])
{
    if(argc<2){
        printf("Please input a file !\n");
        exit(0);
    }
    int sock;
    struct sockaddr_in toAddr;
    struct sockaddr_in fromAddr;
    
    unsigned int fromLen;
    char recvBuffer[128];
    sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    if(sock<0){
        printf("Sock failed!\n");
        exit(1);
    }    
    
    memset(&toAddr,0,sizeof(toAddr));
    
    toAddr.sin_family=AF_INET;
    toAddr.sin_addr.s_addr=inet_addr("10.11.1.88");
    toAddr.sin_port=htons(6601);
    
    /*Get the xmlfile and parse into string*/
    xmlDocPtr doc;      /*file descriptor of the xml*/
    xmlChar *xmlbuf;
    char *szDocName;
    int buffersize;

    szDocName = argv[1];

    /*Open with GB2312*/
    doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER);
    xmlDocDumpFormatMemory(doc, &xmlbuf, &buffersize, 1);
    printf((char *) xmlbuf);

    while(1)
    {
        sleep(1);

        if(sendto(sock,xmlbuf,strlen(xmlbuf)+1,0,(struct sockaddr *)&toAddr,sizeof(toAddr)) == -1){
            printf("Sendto failed!\n");
            exit(2);
            }
    
    printf("OK!\n");
    }
    close(sock);
}
xml:

点击(此处)折叠或打开

  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的学习地址:

阅读(1014) | 评论(0) | 转发(0) |
0

上一篇:linux C解析xml

下一篇:git 搭建

给主人留下些什么吧!~~