1

我正在尝试通过 POST 请求(c++ 和 winapi)将文件发送到 HTTP 服务器,步骤:

// Read file into "buff" and file size into "buffSize" 
        ....
    ....
    ....

    HINTERNET internetRoot;
    HINTERNET httpSession;
    HINTERNET httpRequest;

    internetRoot = InternetOpen(agent_info, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);

    //Connecting to the http server
    httpSession = InternetConnect(internetRoot, IP,PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);

    //Creating a new HTTP POST request to the default resource on the server
    httpRequest = HttpOpenRequest(httpSession, TEXT("POST"), TEXT("/Post.aspx"), NULL, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, NULL);

    //Send POST request
    HttpSendRequest(httpRequest, NULL, NULL, buff, buffSize);

    //Closing handles...

在服务器中,我正在使用此代码(asp.net)接收文件

Stream httpStream;
        try
        {
            httpStream = request.RequestContext.HttpContext.Request.InputStream;
        }
        catch (HttpException)
        {
            return;
        }

            byte[] tmp = new byte[httpStream.Length];
            int bytesRead = httpStream.Read(tmp, 0, 1024 * 1024);
            int totalBytesRead = bytesRead;
            while (bytesRead > 0)
            {
                bytesRead = httpStream.Read(tmp, totalBytesRead, 1024 * 1024);
                totalBytesRead += bytesRead;
            }
            httpStream.Close();
            httpStream.Dispose();

           //Save "tmp" to file...

我可以在本地服务器(visual studio asp 服务器)上发送大文件,但我不能将超过 1 MB 的文件发送到互联网服务器。(HttpOpenRequest 失败)有没有更好的上传文件的方法?

4

2 回答 2

1

警告:这些天我的 Wininet 非常生锈。

我想知道您是否应该自己设置“Content-Length”标头。您的代码似乎假设 a)您正在发出 HTTP/1.0 请求或 b)HttpSendRequest将为您添加标头(我认为它不会)。

无论哪种方式,如果服务器无法快速确定请求大小,则 IIS 的默认配置将拒绝传入请求的大小。

我的猜测是,如果您使用函数的lpszHeadersanddwHeadersLength参数HttpSendRequest包含适当的“Content-Length”标头,问题将得到解决。

于 2012-04-12T22:03:13.773 回答
1

你收到什么错误?我的意思是 GetLastError() 返回什么?如果您发送文件 800KB 那么它可以正常工作吗?我真的不明白如何,因为 HttpOpenRequest 不知道数据的大小。

也许它超时?但这意味着 HttpSendRequest 实际上失败了。它可能会缓冲所有数据,但由于大小很大,因此它需要比超时允许的时间更多的时间。

使用以下代码查询当前超时(以毫秒为单位):

InternetQueryOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut, sizeof(dwReceiveTimeOut));
InternetQueryOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, sizeof(dwSendTimeOut));

并按照以下设置新的:

InternetSetOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwNewReceiveTimeOut, sizeof(dwNewReceiveTimeOut));
InternetSetOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwNewSendTimeOut, sizeof(dwNewSendTimeOut));
于 2012-04-12T22:26:31.420 回答