Gsoap开发之结构体数据输出(对Server而言)

原创 2015年07月07日 16:41:12

头文件Netinterface.h如下:

struct ns__ipAddr
{
    char *ns__ip;
    int  ns__index;
};

struct ns__ipTable
{
};


struct ns__ipTableResponse
{
    struct ns__ipAddr *__ptr;
    int __size;
};
int ns__getIpTable(struct ns__ipTable *ipTab_In,    struct ns__ipTableResponse* ipTable_Out);

接口为ns__getIpTable,  第一个形参为输入(相对Server而言,下同),第二个形参为输出结构体。 

结构体ns__ipTableResponse内成员一定要是__ptr, 并且要指定__size,它们前面都不能加命名空间,加了后用soapcpp2生成的代码是有问题的,无法完成多个结构体传送的目的,这个事情折腾了很久,尽管在网上能找到一些答案,当时成员类型是一样的,但成员名却跟这个不一样,浪费了两天多时间,这也算是自负的后果吧。 所以一定记得要用上一样的成员名,这个估计是生成器能识别到的名字,它是根据这个来生成结构的。

具体有何不同呢? 可以试着把成员名__ptr改成ns__ptr, 你再去看看生成的soapStub.h里有没有这个结构体? 怕是没有吧! 

#ifndef SOAP_TYPE_ns__getIpTableResponse
#define SOAP_TYPE_ns__getIpTableResponse (20)
/* ns:getIpTableResponse */
struct ns__getIpTableResponse
{
	struct ns__ipTableResponse *ipTable_Out;	/* SOAP 1.2 RPC return element (when namespace qualified) */	/* optional element of type ns:ipTableResponse */
};
#endif

找到soapcpp2执行文件,新建一个工程目录后进入,在terminal里执行$ ./soapcpp2 -c Netinterface.h  

-c 是生成纯C的SOAP代码架构的意思,这些可以参看soapcpp2命令说明。 OK,生成架构后即可开始码代码了。

Server端:

下面的目录文件ipaddr内容为:

10.0.0.234
10.0.0.235
10.0.0.236
10.0.0.237

#define  myTable   "/etc/ipaddr"
#define  IP_LEN    4
#define  IP_BUF    100
#define  IPADDR_LEN   16

int getIpInfoBySys()
{
	int i=0;
	FILE *fp_ipaddr;
	fp_ipaddr = fopen(myTable, "r");
	if(fp_ipaddr == NULL)
	{
	     printf("error\n");
	     return -1;
	}

	char line[IP_BUF];
	while(!feof(fp_ipaddr))
	{
		memset(strIP[i], '\0', IP_BUF);
		memset(line, '\0', IP_BUF);
	    fgets(line, sizeof(line), fp_ipaddr);
	    line[strlen(line)-1] = '\0';
		sprintf(strIP[i], "%s", line);
		i++;
		if(i > IP_LEN-1)
			break;
	}
	fclose(fp_ipaddr);
	fp_ipaddr = NULL;
	return 0;
}


int
main (int argc, char *argv[])
{
	int m, s;
	struct soap mySoap;
	soap_init (&mySoap);

	mySoap.bind_flags = SO_REUSEADDR;
	mySoap.fget = http_get;
	soap_set_namespaces(&mySoap, namespaces);


	soap_set_recv_logfile(&mySoap, "./log/S_RECV.log");
	soap_set_sent_logfile(&mySoap, "./log/S_SENT.log");
	soap_set_test_logfile(&mySoap, "./log/S_TEST.log");


	if (argc < 2)
	{
		  printf ("usage: %s <server_port> \n", argv[0]);
		  exit (1);
	}
	else
	{
		  m = soap_bind (&mySoap, NULL, atoi (argv[1]), 100);
		  if (m < 0)
		  {
			  soap_print_fault (&mySoap, stderr);
			  exit (-1);
		  }
		  fprintf (stderr, "Socket connection successful: master socket = %d\n",m);
		  for (;;)
		  {
			  s = soap_accept (&mySoap);
			  if (s < 0)
			  {
				  soap_print_fault (&mySoap, stderr);
				  exit (-1);
			  }
			  fprintf (stderr,
					  "Socket connection successful: slave socket = %d\n", s);
			  soap_serve (&mySoap);    //该句说明该server的服务
			  soap_end (&mySoap);
		  }
	}
	return 0;
}

int 
ns__getIpTable(struct soap *mySoap, struct ns__ipTable *ipTab_In,  struct ns__ipTableResponse* ipTable_Out)
{
	if(getIpInfoBySys() != 0)
	{
		printf("getIpInfoBySys failed\n");
		return -1;
	}
        
	ipTable_Out->__size = 4;
	struct ns__ipAddr * myIpAddr = (struct ns__ipAddr *)soap_malloc(mySoap, ipTable_Out->__size * sizeof(struct ns__ipAddr));

	ipTable_Out->__ptr = myIpAddr;

	int i=0;

	for(i=0; i<ipTable_Out->__size; i++)
	{
		myIpAddr[i].ns__index = i;
		myIpAddr[i].ns__ip = (char *)soap_malloc(mySoap, IPADDR_LEN);
		memset(myIpAddr[i].ns__ip, '\0', IPADDR_LEN);
		strncpy(myIpAddr[i].ns__ip, strIP[i], IPADDR_LEN);

        printf("%d--%s\n", myIpAddr[i].ns__index, myIpAddr[i].ns__ip);
	}
	return 0;
}

Client端:

  /****************Main********************/
   struct ns__ipTableResponse ipTable;
   result = getIpTable (server, "", &ipTable);
   if (result != 0)
   {
       printf ("getIpTable failed\n");
   }
   /************************************/


int
getIpTable (const char *server, struct ns__ipTable *ipTab_In,  struct ns__ipTableResponse* ipTable_Out)
{
	struct soap mySoap;                         /* 创建mySoap()结构体 */
	int result = 0;
	soap_init (&mySoap);                        /* soap_init()*/
	soap_set_namespaces(&mySoap, namespaces);

#ifdef  __DEBUG
	soap_set_recv_logfile(&mySoap, "./log/C_RECV.log");
	soap_set_sent_logfile(&mySoap, "./log/C_SENT.log");
	soap_set_test_logfile(&mySoap, "./log/C_TEST.log");
#endif

	soap_call_ns__getIpTable (&mySoap, server, "", ipTab_In, ipTable_Out); /* 调用soap_call_ns__getIpTable() */
	if (mySoap.error)
    {
			printf ("soap error:%d,%s,%s\n", mySoap.error,
          *soap_faultcode (&mySoap), *soap_faultstring (&mySoap));
			result = mySoap.error;
    }
	else
	{
			printf ("size of IPaddr  is %d\n", ipTable_Out->__size);
			int cnt=0;
			for(cnt = 0; cnt < ipTable_Out->__size; cnt++)
			{
				printf("index--%d, IpAddress is %s\n", (ipTable_Out->__ptr + cnt)->ns__index, (ipTable_Out->__ptr + cnt)->ns__ip);
			}

	}

	soap_end (&mySoap);                         /* 释放内存空间 */
	soap_done (&mySoap);
	return result;
}

最后,分别执行Server及Client端应用即可。

PS: 要善于利用wireshark网络抓包工具,对协议包进行分析,另外也要会用gsoap提供的debug log, 从里面可以看出很多问题。 我的一个内存出错问题还有结构体传送异常问题也都是通过它找到答案的。
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Gsoap开发之结构体数据输入(对Server而言)

gSOAP一种跨平台的C和 C++软件开发工具包。生成C/C++的RPC代码,XML数据绑定,对SOAP Web服务和其他应用形成高效的具体架构解析器,它们都受益于一个XML接口。
  • nszjh
  • nszjh
  • 2015-07-07 17:16
  • 700

基于gsoap开发WebService服务返回结构体数组

基于gsoap开发WebService服务返回结构体数组 gsoap搭建和快速WebService示例编写,前面文章已经介绍过,此文直接讲关键点。 (1)返回的目标结构,开头以ns...

gsoap_返回值为结构体数组

  • 2016-07-29 10:51
  • 1.25MB
  • 下载

C++调用gSoap编写的WEBSERVICE与C#.NET间接口自定义结构体不能重复使用

最近项目开发从C/S架构转成B/S架构后,开始使用webservice技术,由于我们的webservice是由vc++实现的,因此用到了gSoap库实现webservice,而上端业务我们采用了C#编...
  • acidy
  • acidy
  • 2014-02-23 15:22
  • 1192

C++培训_003_数据类型_结构体_基础输入输出

C++数据类型 名称空间

Golang web 开发实战之 session 缓存:如何使用 redigo 将一个结构体数据保存到 redis?

自定义 session 结构体:type Session struct { SessionID string `json:"sessionId" bson:"sessionId"` ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)