在linux下常常要進行socket通訊,而數據流多采用目前流行的xml格式,這就會有兩個用的比較多的功能:
一、接收端將收到的字符串轉換成xml格式的數據;
二、發送端將xml格式的數據轉換成字符串發送。html
運用libxml2組件進行上述操做其實是xmlDocPtr和xmlChar兩種類型之間的轉換。node
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*)強行轉換也行。linux
(以上,轉自http://hi.baidu.com/dante300/blog/item/b0962f51e472261d0cf3e3ad.html)socket
下面的例子,srv端等待6601端口的數據,並使用XML解析,取得其中的name和age項,並打印到終端學習
client端讀取一個XML文件,並把讀取的數據轉換爲字符串,向服務端的端口發送.net
[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 -lxml2orm
LIBXML2的學習地址:http://www.xmlsoft.org/html/libxml-tree.htmlxml