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

在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<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);
}
使用的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的学习地址:http://www.xmlsoft.org/html/libxml-tree.html

阅读更多
个人分类: Linux网络编程
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭