c语言直接写soap客户端-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 1235609
  • 博文数量: 76
  • 博客积分: 1959
  • 博客等级: 上尉
  • 技术积分: 2689
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-19 12:07
个人简介

樽中酒不空

文章分类

全部博文(76)

文章存档

2020年(4)

2019年(1)

2017年(2)

2016年(2)

2015年(7)

2014年(11)

2013年(13)

2012年(18)

2011年(2)

2010年(16)

相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: c/c

2010-08-26 09:16:48

原理大家都知道,直接看代码:
(注明:在其他网站可能会看到同样内容的文章,不是抄袭,都是本人之作。只不过看那个网站不顺眼,把文章移到这上面来了)

对于一个c程序员来说,写webservice是件比较头痛的事。好在ms下有相应的toolkit,在vc2003开始,编译环境已经集成了相关功能,

点"project->add web reference",显示一个对话框,把一.个wsdl的地址写上,会自动分析生成相关的c 的 class,然后就可以用了。

开源软件,有个很不错的产品叫gsoap,使用起来应该更简单,google上能找出很多文章来介绍。这个产品是多平台的,最简单的使用方法就是下 载其二进制文件,一共有两个,wsdl2h 和soapcpp2,看名字就知道了, 前者把wsdl转成.h,后者再根据这个.h生成相关的class 或函数。用的时候,把生成的几个.h,.c放在自己的工程目录下,再到gsoap源码中找出stdsoap2.h和stdsoap2.cpp,都放进工 程,不用引入任何lib或dll,直接使用就可以了。stdsoap2.cpp这里面已经实现了socket的通信功能。

ms自己的soap功能已经淘汰一些不太安全的方式,所以有些webservice解析出错,比如最近用到的一个关于rpc的,ms不支持。gsoap兼容性相对好一些, 可以用。

而且,gsoap最大的好处,就是可以跟踪调试源码,比如提交时的http字符串内容,接收到的http字符串,直接可以显示出来,省的再用抓包工具了。在调试方面来讲,gsoap远远超过了ms,想想对com进行调试,没几年的经验是弄不好的。

gsoap在linux下工作也很不错,使用方法和windwos下完全一样,先把wsdl解析出来,然后直接使用.h和.c。

最近调试一个webservice,检查的非常苛刻,比如http里的content-length,一般写为0就可以了,然后会检查\r\n\r \n,表示结束。但这个服务器端非要知道content-length的数值,然后再检查结束符,如果这里写0,直接返回错误。调试了一下gsoap,发 现如果不特意指定的话,content-length总是置为0。不过这个问题相对也很好解决,只是在调试代码中,很快就了解了soap底层的一些实现过 程,然后自己用socket仿照也实现了一个简单的。

代码演示如下:

//*****************

//file: main.c

//*****************

#include
#pragma comment(lib, "ws2_32.lib")

int m_hsocket;
int connect( const char* szhostaddr, int nport )  
{  
    sockaddr_in sockaddr;   
    memset(&sockaddr,0,sizeof(sockaddr));  
      
    sockaddr.sin_family = af_inet;  
    sockaddr.sin_addr.s_addr = inet_addr(szhostaddr);  
      
    if (inaddr_none == sockaddr.sin_addr.s_addr)  
    {  
        lphostent lphost;  
        lphost = gethostbyname(szhostaddr);  
        if (lphost != null)  
            sockaddr.sin_addr.s_addr = ((lpin_addr)lphost->h_addr)->s_addr;  
        else  
        {  
            wsasetlasterror(wsaeinval);  
            return false;  
        }  
    }  
      
    sockaddr.sin_port = htons((u_short)nport);
 
      
    if (socket_error == connect(m_hsocket, (lpsockaddr)&sockaddr, sizeof(sockaddr)))  
    {  
        //int nerror = wsagetlasterror();  
        return -1;  
    }  
    return 0;  
}  

//length应该足够大,timeout单位是秒
int tcprecvtimeout(int fd, char* buffer, int length, int timeout)
{
 struct timeval timeout;
 int recv_lenth = 0;
 //int left_length = length;
 int fd_max=fd 1;
 int sel_ret=0, recv_ret=0;
 fd_set fdset ;

 timeout.tv_sec = timeout;
 timeout.tv_usec = 0;

 fd_zero(&fdset);
 fd_set(fd, &fdset);
 sel_ret = select(fd_max, &fdset, null, null, &timeout);

 if (sel_ret > 0)
 {
  while (1)
  {
   //while (sel_ret==-1 && errno == eintr);
   recv_ret = recv(fd, buffer, length, 0/*msg_nosignal*/);
   if (recv_ret > 0)
   {
    recv_lenth = recv_ret;
    //left_length -= recv_ret;
    buffer = recv_ret;
   }
   else if (recv_ret == 0)//socket close
   {
    return recv_lenth;
   }
   else if (recv_ret < 0)//socket_error
   {
    return recv_lenth;
   }
  }
 }
 else if (sel_ret < 0)
 {
  return -1;
 }
 else//sel_ret == 0
 {
  //超时
  return 0;
 }
 return recv_lenth;
}

int tcpsend(int fd, char* buffer, int length)
{
 int left_length = length;
 int send_ret = 0;

 while (left_length>0)
 {
     send_ret = send(fd, buffer, left_length, 0);
    if (send_ret < 0)
  {
   return -1;
  }

  if (send_ret < left_length)
  {
   left_length -= send_ret;
   buffer = send_ret;
  }
  else
  {
   left_length = 0;
   break;
  }

  if ((left_sec -= 2) <= 0)
  {
   break;
  }
 }

 return (left_length<0) ? length : length-left_length;
}

// 发送字符串,最关键的是组http头,如果这里组不好,服务器响应就有问题

int send_xml()
{

char* psend;//要发送的内容,应该是一组xml字符串

_snprintf(tmp, 4096,
 "post /monitorservice/services/configservicesoap http/1.1\r\n"
 "content-type: text/xml\r\n"
 "user-agent: xml spy\r\n"
 "soapaction: \""
 "host: 127.0.0.1:8081\r\n"
 "content-length: %d\r\n"
  "\r\n"
 "\r\n"

  %s,

  strlen(psend),psend);

//组包结束,开始发送

return tcpsendtimeout(m_hsocket,tmp, leng);

 

}

int main()
{
 int nret = 0;
 char buff[2048];
 wsadata wsadata;   
 wsastartup(makeword(2,2),&wsadata);
 
 if ((m_hsocket = socket(af_inet, sock_stream, 0)) == -1)
    {
        perror("创建套接字失败");
        exit(errno);
    }
    else
    {
        printf("创建套接字成功\n");
    }

 
 nret = connect("127.0.0.1", 8081);

 if (nret != 0)

{

    exit(errno);
}

 send_xml();//这里发送字符串

 nret = tcprecvtimeout(m_hsocket, buff, 2048, 5);
 close(m_hsocket);

 if (nret > 0)

 {

      //收到webservice值,开始解析,接收的内容先是http信息头,然后跟着是xml格式的字符串

  }

 wsacleanup();

  
 return 0;
}


阅读(8471) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

sxcong2010-09-01 09:39:20

下载后,分析内容,见: http://blog.chinaunix.net/u1/54401/showart.php?id=2315660

|

chinaunix网友2010-08-29 08:18:02

download more than 1000 free it ebooks: http://free-ebooks.appspot.com

|
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图