使用Wininet API上传文件到Web Server

使用Wininet API上传文件到Web Server。它分为客户端和服务端两块,客户端负责连接服务器,发送数据给服务端;服务端负责接收数据,保存。

首先看客户端:
    在这里,需要稍微解释下URL的组成。举个例子:http://myWebServer:8080/Handler/FileUploader.aspx
    其中 "myWebServer"为Server Host Name,它用来表示服务器的IP地址。
    “8080”是该服务器对http开发的端口号,如不指定的话,默认为80
    “/Handler/FileUploader.aspx”就是这个URL的UrlPath了

    使用Wininet API同服务器打交道,知道这么多久可以了,下面看怎么编写客户端代码。其实它的步骤是很死的,只要按固定套路使用就可以了。
    1. 用 InternetOpen 创建一个表示该次连接的Internet句柄
        HINTERNET hInternet = ::InternetOpen(_T("Sample String"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    2. 用 InternetConnect 与指定服务器连接,获得本次连接句柄
        // hInternet就是InternetOpen返回的句柄
        // szServerHostName就是上面例子URL中的“myWebServer”
        // nPort是上例的8080,NULL的话表示默认(80)
        HINTERNET hConnection = ::InternetConnect(hInternet, szServerHostName, nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    3. 连接成功后,下面就开始发送请求,告诉服务器,我要上传文件了。
        // szUrlPath就是上例中的“/Handler/FileUploader.aspx”,注意,最前面的"/"不能省略的。
        // accept是一个LPCTSTR数组,表示该URL接受的文件类型。可以用:
       //     LPCTSTR accept[] = {
       //         _T("*/*"),
       //         NULL
       //     };
       //    表示任何类型
        HINTERNET hRequest = ::HttpOpenRequest(hConnection, _T("POST"), szUrlPath, NULL, NULL, accept, 0, INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_AUTO_REDIRECT|INTERNET_FLAG_HYPERLINK);
        INTERNET_BUFFERS ib;
        memset(&ib, 0, sizeof(INTERNET_BUFFERS));
        ib.dwStructSize = sizeof(INTERNET_BUFFERS);
        ib.dwBufferTotal = dwTotalSize;    //这里是你要传送数据的总大小,比如一个文件的大小::GetFileSize(hFile, 0)
        ib.dwBufferLength = dwBufSize;    //分次上传的话,每次上传数据的大小,比如4里面的dwBufSize

        ::HttpSendRequestEx(hRequest, &ib, 0, HSR_INITIATE, 0));

    4. 请求发送成功后,就可以传送数据了,传送数据使用的是::InternetWriteFile这个API
        DWORD dwBufSize = 1024*1024; //1M
        TCHAR* buffer = new TCHAR[dwBufSize];
        DWORD dwRead;
        ::InternetWriteFile(hRequest, buffer, dwBufSize, &dwRead);
        这样就把数据发送到服务端了。
    5. 紧接着,客户端需要调用HttpEndRequest()等待服务器处理。这个时候,客户端的执行实际上是停止在这里的,只有当服务段接受完数据,完成处理后,客户端才接着执行下去。
    6. 下面就是释放前面申请的句柄和内存了。

    以上是客户端向服务器发送数据的全部过程了,如果想传送文件的话,需要在4里面,用一个循环,将文件数据不断读取到buffer里,并用InternetWriteFile发送出去。
       
服务端:
    服务端就负责接收数据了,以下是C# asp.net的样例。
    其实,也就是用Request不断从管道里读取上传的数据。
    http://myWebServer:8080/Handler/FileUploader.aspx的cs文件

    FileUploader.cs文件
    
    public class FileUpload : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Stream input = Request.InputStream;
            if (input.Length > 0)
            {
                String filepath = MapPath("~/Temp/UploadedFile.dat");
                using (FileStream output = File.Create(filepath))
                {
                    byte[] buffer = new byte[1024];
                    int nTotalBytesWritten = 0;
                    int nRead = input.Read(buffer, 0, buffer.Length);
                    while(nRead > 0)
                    {
                        output.Write(buffer, 0, nRead );
                        nTotalBytesWritten += nRead ;
                        nCount = input.Read(buffer, 0, buffer.Length);
                    }
                }
            }
        }
    }

注意事项:
    1. 上传文件的大小还是受IIS限制的,大约超过1G之后,就Stream input = Request.InputStream;就会出现问题。如果要上传超大文件,比如10G以上,这需要客户端对文件进行处理,分块上传,最后服务端接收分块,最后合并,还原。
    2. 不要在客户端的HttpEndRequest()调用之前使用Session、Response、Request,在对话期间,这些变量都处于连接状态,任何改变都是无效的(比如:Redirect(NewURL),Session这时候是不工作的)。
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值