在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 plain copy
- /*srv.c By ksir in 2011-10-14*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <libxml/parser.h>
- #include <libxml/xmlmemory.h>
- #define MAXLINE 80
- int port = 6601; /*Port of socket*/
- /*parse XML and show content of 'name','age'*/
- int parseXML(xmlDocPtr tmpdoc)
- {
- //printf("This is in parseXML\n");
- xmlNodePtr curNode; /*Keep node of the xml tree*/
- xmlChar *szKey;
- /*Get the root Node from tmpdoc*/
- curNode = xmlDocGetRootElement(tmpdoc);
- /*check the content of the document*/
- if (NULL == curNode)
- {
- xmlFreeDoc(tmpdoc);
- return -3;
- }
- /*Check the type of the root element*/
- if(xmlStrcmp(curNode->name,BAD_CAST"n"))
- {
- printf("Document of the wrong type");
- xmlFreeDoc(tmpdoc);
- return -4;
- }
- curNode = curNode->xmlChildrenNode;
- xmlNodePtr propNpdePtr =curNode;
- while (curNode != NULL)
- {
- /*compare element nodes,show the content*/
- if( !(xmlStrcmp(curNode->name,(const xmlChar *)"name")))
- {
- szKey = xmlNodeGetContent(curNode);
- printf("name:%s\n",szKey);
- xmlFree(szKey);
- }
- else if( !(xmlStrcmp(curNode->name,(const xmlChar *)"age")))
- {
- printf("Age:%s\n",xmlNodeGetContent(curNode));
- }
- /*traverse*/
- curNode = curNode->next;
- }
- xmlFreeDoc(tmpdoc);
- return 0;
- }
- int main(void)
- {
- struct sockaddr_in sin;
- struct sockaddr_in rin;
- int sock_fd;
- int address_size;
- char buf[MAXLINE];
- char str[INET_ADDRSTRLEN];
- int len;
- int n;
- xmlDocPtr doc;
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(port);
- sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (-1 == sock_fd)
- {
- perror("call to socket");
- exit(1);
- }
- n = bind(sock_fd, (struct sockaddr *)&sin, sizeof(sin));
- if (-1 == n)
- {
- perror("call to bind");
- exit(1);
- }
- while(1)
- {
- address_size = sizeof(rin);
- n = recvfrom(sock_fd,buf,MAXLINE,0,(struct sockaddr *)&rin,
- &address_size);
- if (-1 == n)
- {
- perror("call to recvfrom.\n");
- exit(1);
- }
- // printf("you ip is %s at port %d:%s\n",
- // inet_ntop(AF_INET, &rin.sin_addr,str,sizeof(str)),
- // ntohs(rin.sin_port),(char *)buf);
- /*transfer buf to xml*/
- doc = xmlParseMemory((char *)buf,strlen(buf)+1);
- if (NULL == doc)
- {
- printf("xmlParseMemory fail\n");
- return -2;
- }
- parseXML(doc);
- }
- return 0;
- }
客户端代码:
[cpp] view plain copy
使用的XML文件:
- /*Client.c by ksir in 2011-10-14*/
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<unistd.h>
- #include<sys/socket.h>
- #include<linux/in.h>
- #include <libxml/parser.h>
- #include <libxml/xmlmemory.h>
- 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);
- }
[html] view plain copy
- <n>
- <name>
- ksir
- </name>
- <age>
- 18
- </age>
- </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