vc++调用web服务传输文件

bool webService::UploadFile(LPWSTR appKey, LPWSTR fileName, const int len, unsigned char * buff)
{

    try
     {
                 //SoapSerializer用于序列化(串行化),创建,封装SOAP消息.用来构建一个向Web服务发送的SOAP消息
                 ISoapSerializerPtr Serializer;
                 //SoapReader将SOAP消息解析为一个DOM模型,并提供一系列操作该DOM模型的方法
                 ISoapReaderPtr  Reader;
                 //SoapConnector在对象之间发送和接收SOAP消息的传输协议
                 ISoapConnectorPtr Connector;

                 IDataEncoderFactoryPtr encoderFc;

                 //创建一个Connector对象
                 Connector.CreateInstance(__uuidof(HttpConnector30));
                 //Web服务是由Property(HttpConnector的一个属性)指定的
                 //在处理这一属性时有件事情需要指定:我们引用的哪个属性以及该属性的值
                 //EndPointURL属性指定Web服务
                 Connector->Property["EndPointURL"] = "http://127.0.0.1/Services/UploadService.asmx?wsdl";//web服务的URL
                 ////////////////////////////////////////////////////////////////////////////
                 //Connector->Property[参数]说明,对大小写敏感
                // AuthPassword: 端点认证用的口令。
                // AuthUser:  端点认证用的用户名
                // EndPointURL : 端点的URL
                // ProxyPassword: 代理认证的口令
                // ProxyPort : 代理服务器使用的端口
                // ProxyServer : 代理服务器的IP地址或主机名
                // ProxyUser : 代理认证的用户名
                // SoapAction: HTTP头部中SoapAction中的值。这个属性只使用于低级API。它将忽略SoapClient接口(高级API)中的ConnectorProperty属性 。
                // SSLClientCertificateName:指定使用Secure Sockets Layer (SSL)加密协议(如果存在,则该字符串标明用于SSL协议中的客户端证书)。语法如下:
                //  [CURRENT_USER | LOCAL_MACHINE\[store-name\]]cert-name with the defaults being CURRENT_USER\MY (与Microsoft Internet Explorer用法相同)。
                // Timeout:  HttpConnector的超时限制,以毫秒为单位。
                // UseProxy:  一个类型为布尔型的属性,表明是否使用代理服务器。缺省情况下,这一属性的值被设定为False,表明无需使用代理服务器。如果要使用代服务器,需要将该属性的值设置为True。如果将该属性的值设置为True, 而又没有设置ProxyServer属性,HttpConnector将使用IE中设置的代理服器。HttpConnector会忽略IE中的“不使用代理服务器”设置。
                // UseSSL:  表明是否使用了SSL的布尔型值。如果该属性被设置为True,则无论WSDL中是否指定了HTTP或HTTPS,HttpConnector对象都使用SSL连接。
                //     如果该属性的值被设置为False,则只有在WSDL中指定了HTTPS的情况下, HttpConnector对象才会使用SSL连接
                // 详细请参考:http://www.codesky.net/article/200504/62841.html
                 ///////////////////////////////////////////////////////////////////////////

                 Connector->Connect();
                 //开始消息
                 Connector->Property["SoapAction"] = "http://tempuri.org/Append";
                 //开始SOAP消息
                 //在完成与Web服务的连接和其他的细节后,我们就可以调用向服务器发送SOAP信息的方法了,必须在调用SoapSerializer的其他方法之前调用该方法
                 Connector->BeginMessage();
                 //创建SoapSerializer对象
                 Serializer.CreateInstance(__uuidof(SoapSerializer30));
                 //将serializer连接到connector的输入字符串
                 //在与服务器连接前,SoapSerializer对象必须与SoapConnector对象连接。
                 //为了使这二个对象相互连接,我们需要调用SoapSerializer对象的Init方法,该方法需要一个参数InputStream(向服务器发送数据的流)
                 Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
                 //创建SOAP消息
                 //开始处理SOAP消息,
                 //第一个参数是命名空间,缺省为SOAP-ENV,第二个参数定义URL,第三个参数定义Serialzier->startBody("")函数的编码方式。
                 Serializer->StartEnvelope("","","");
                 //开始处理Body元素,参数为URI的编码类型,缺省为NONE
                 Serializer->StartBody("");
                 //开始处理Body里的子元素
                 //第一个参数是元素名,第二个参数是URL,第三个参数是编码类型,第四个参数是元素的命名空间
                 ///////////Serializer->StartElement("HelloWorld",    "http://localhost:42782/","","soap");
                 Serializer->StartElement("Append",    "http://tempuri.org/","","soap");
                 //WebXml.com.cn是Web服务所属的名称空间(如果Web服务提供者没有指定名称空间,将会使用该默认名称空间)。
                ///////// Serializer->StartElement("theCityName","","","soap");
                 //写入元素值,
                ////////// Serializer->WriteString("郑州");
                 //上面的每个startXXX函数后都要有相应的endXXX函数来结尾
                /////// Serializer->EndElement();
                    //密钥(自定义web服务中的参数)
                 Serializer->StartElement("appKey","","","soap");
                 Serializer->WriteString(appKey);
                 Serializer->EndElement();

          //文件名称(自定义web服务中的参数)
                 Serializer->StartElement("fileName","","","soap");
                 Serializer->WriteString(fileName);
                 Serializer->EndElement();

                 /********************传输二进制数据*****************************/
                    HRESULT hr = FALSE;
                   encoderFc.CreateInstance(__uuidof(DataEncoderFactory30));
                    DWORD *len1=new DWORD;
                   IDataEncoderPtr encoder=encoderFc->GetDataEncoder(L"base64");
                    encoder->raw_SizeToEncode(buff,len,len1);
                    int lon = *len1;
                    byte *data = new byte[lon+1];
                    hr=encoder->Encode(buff,len,data,len1);
                    if(FAILED(hr)){
                        TRACE("Encode error! ");
                    }
                    int len2 = *len1;

                 Serializer->StartElement("buffer","","","soap");
                 Serializer->WriteBuffer(len2, (byte*)data);
                 delete len1;
                delete[] data;           //结束

                 Serializer->EndElement();
               /********************结束传输二进制数据*****************************/
                 Serializer->EndElement();
                 Serializer->EndBody();
                 Serializer->EndEnvelope();
                 //消息做完之后,连接器就调用endMessage()方法将消息发送到服务器
                 Connector->EndMessage();
                 //创建响应soap消息
                 Reader.CreateInstance(__uuidof(SoapReader30));
                 //OutPutStream来读取SoapReader对象中的信息
                 //将reader连接到connector的输出字符串
                 Reader->Load(_variant_t((IUnknown*)Connector->OutputStream),"");
                 //将回应信息加载到SoapReader对象后,就可以用它的RpcResult属性来获取结果,
                 //但是RpcResult并不直接返回结果,它返回Body的第一个实体元素
                 //然后用text属性读取该元素的属性值
                 return ((const char*)Reader->RpcResult->text)=="true";

                /* printf("%s\n",(const char*)Reader->RpcResult->text);
                 MessageBoxA(NULL, Reader->RpcResult->text, "提示", MB_OK);*/
     }
     catch(_com_error &e)
     {
        printf("%s",e.ErrorMessage());
     }

    return 0;
}

2、web服务接口:

 /// <summary>
    /// 上传文件到服务器
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="buffer"></param>
    /// <returns></returns>
    [WebMethod]
    public bool Append(string fileName, string buffer,string appKey)
    {

        bool isAppend = true;
        try
        {
            fileName = Path.Combine(@"d:\"+ Path.GetFileName(fileName) + ".txt");
            if (!File.Exists(fileName))
            {
                CreateFile(fileName,appKey);
            }
            byte[] fileBuff = Convert.FromBase64String(buffer);

            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
            fs.Seek(0, SeekOrigin.End);
            fs.Write(fileBuff, 0, fileBuff.Length);
            fs.Close();
        }
        catch(Exception e)
        {
            string text = e.Message;
            isAppend = false;
        }
        return isAppend;
    }

注意需要使用到:SoapToolkit3.0 开发包,开发的时候需要安装到本地,发布的时候不安装该客户端的步骤:

1、修改头部文件:

#import "msxml4.dll"  named_guids

//FOR SOAPTIOOLKIT 3.0
#import "MSSOAP30.dll" named_guids   exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER",   "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")

2、将该目录下的所有文件复制到程序运行目录下“C:\Program Files (x86)\Common Files\MSSoap\Binaries\”,另外还需要复制msxml4r.dll msxml4.dll 两个文件。注意这两个文件创建时间都是2002-2-4其它时间的我这里报错

3、然后再注册相关文件:

最后在程序目录下执行:

regsvr32 "MSSOAP30.dll"
regsvr32 "Resources\1033\MSSOAPR3.dll"
regsvr32 "WISC30.dll"regsvr32 "msxml4.dll"

参考:https://www.1wanweb.com/post/vc2b2b60-mfc-soapsdke5bc80e58f91websesrvicee68993e58c85.aspx

时间: 2024-09-30 18:26:37

vc++调用web服务传输文件的相关文章

asp.net(c#)用Ajax调用web 服务实现省市县三级联动

1.先说说硬件配置,我最开始是在Win7(I7 4770,8G RAM,2T硬盘)里装ubuntu10.10 64位系统(4G RAM,200G 硬盘)进行源码编译,大概花了3个多小时.而且还多次出现outofmemoryerror 错误.最后将硬件升级为I7 4770.16G内存.2T硬盘,不装虚拟机,直接跑Ubuntu 10.10系统,Swap分区为16G,编译一次大概花了40分钟,没有报任何错误. 所以不推荐在虚拟机里面跑. 2.根据官方文档配置编译环境: 官方文档说的是在"发布包/Sof

VS2013创建和调用Web服务

说到Web服务,我们主要有两种途径去创建和调用它,一种是基于Java的web服务,主要是JAX为主的:另一种是ASP.NET的方式去实现:相比之下,笔者更喜欢后者的实现方式,所以推出了Visual Studio的webservice教程. 第一步:先创建一个工程 第二步:选择Visual C#下面的Web项目,基于.NET4.5 第三步:创建服务方法 第四步:发布这个项目 第五步:配置发布选项 第六步:发布选项配置完成之后点击Finish 第七步:配置IIS,一般人的电脑上都没有预先配置这个,所

CXF调用web服务

1.进入apache-cxf-2.7.6\bin目录,按住shift键,鼠标右键点击选择:  在此处打开命令窗口 2.输入 wsdl2java url ,url是对外发布的端口  ,    发布web服务示例: http://www.cnblogs.com/taobd/p/6691871.html 3.把生成的java文件复制到项目,示例如下: 1 package cn.bd.client; 2 import java.util.Date; 3 import javax.xml.bind.ann

mvc路由引起异步调用web服务的问题

从一篇blog得知使用脚本可以异步调用Web服务,觉得很新鲜,因为自己很少用到Web服务,所以决定写一写看看什么效果. 首先在UI项目(我使用的是MVC4.0)里创建一个Web服务. 添加Web服务后,默认有一个HelloWorld方法.调用该方法有两种形式,一是服务端通过实例化对象调用,二是前端脚本异步 调用.代码分别是: 1.服务端调用 public ActionResult Index() { WebService1 ws = new WebService1(); var str = ws

使用ASP.NET AJAX 从脚本中调用Web 服务的应用方法

技能点:通过编写WebService,在页面js中调用WebService来进行数据查询. 网站开发,有些时候需要使用js在页面动态生成一些内容,但还有些数据要通过查询数据库才能获取的. 但由于诸如主键id等一些关键数据在后台不易获取,或在后台获取数据后不易直接在前台通过js使用. 这种情况下,使用js+ajax的方式来实现,效果也是不错的. 1.编写webservice: 1 using System; 2 using System.Collections.Generic; 3 using S

动态调用web服务,当有实体类的时候 (只用于一个)

public class CCBWebSeviceHelper { public static int rowCount = 0; /// < summary> /// 动态调用web服务,当有实体类的时候 (只用于一个) /// < /summary> /// < param name="url">WSDL服务地址< /param> /// < param name="classname">类名<

在 SQL Server 的存储过程中调用 Web 服务

介绍 一个老朋友计划开发一个应用,基于 .NET 和 Socket,但需要在存储过程中调用 Web 服务. 在这篇文章中我们将分享这个应用的经验,讲述如何在存储过程中调用 Web 服务,并传递参数. Step 1 首先我们在 Visual Studio 中创建一个 Web 服务项目: Step 2 接下来在服务中添加我们需要的方法,在这里我们创建 6 个方法,分别是 Greet (string Param1) ,HelloWord() , Add, subtract, 和 Divide (Num

CentOS 7.0 使用Vsftpd服务传输文件

CentOS 7.0 使用Vsftpd服务传输文件 文件传输协议 文件传输协议(FTP,File Transfer Protocol),即能够让用户在互联网中上传.下载文件的文件协议,而FTP服务器就是支持FTP传输协议的主机,要想完成文件传输则需要FTP服务端和FTP客户端的配合才行. 通常用户使用FTP客户端软件向FTP服务器发起连接并发送FTP指令,服务器收到用户指令后将执行结果返回客户端. FTP协议占用两个端口号: 21端口:命令控制,用于接收客户端执行的FTP命令. 20端口:数据传

在 PHP 中使用 SOAP 协议调用 Web服务(WebService)

使用 PHP 中调用 WebService,听上去有些高深莫测啊. 其实这是很简单的一件事.由于 Web服务完全是基于 XML 这种平台无关性的标记语言来实现的,所以在 PHP中实现访问 WebService 是可能的.本例我们来完成这样一个 Web服务的调用:获取手机号信息.在互联网上找到这样一个 Web服务是比较容易的,这里我为大家提供一个现成的:http://www.webxml.com.cn/zh_cn/web_services_item.aspx?id=776756327947797A