在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文件,并把读取的数据转换为字符串,向服务端的端口发送
-
/*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;
-
}
客户端
/*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:
-
<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的学习地址:
阅读(1014) | 评论(0) | 转发(0) |