我实现一个向HTTP1.1服务器上传文件的功能,HTTP1.1服务器的WEB地址是固定的,我客户端会每次最多同时上传2个文件!因为HTTP发送大文件会超时,所以文件采用分块传输的方法,每一块的大小是1M。
我查看了MSDN的例子后写了如下函数 ,发送部分采用了sendrequestex()和endrequest函数(),在线程入口函数中的上传部分代码如下:***注:因为是解决endrequest的问题,所以代码只贴上传这一关键部分的代码,
其中一些变量不作说过多说明
CHttpConnection * pHC = NULL;
CHttpFile * pHF = NULL;
CInternetSession cis;
cis.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 9000);
cis.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 3); //重试次数 pHC = cis.GetHttpConnection(strServer, wPort,temp->user_name,temp->user_password); //带“用户名”“密码”的http连接申请while (send_now>0)
{
int send_this=send_now>1048576?1048576:send_now;//判断每一次循环需要发送的数据大小try
{ m_file.Seek((tailnumber)*1048576,CFile::begin);
tailnumber++; //统计分块传输的次数 pHF = pHC->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject); while(1)
{
int request_ret=pHF->SendRequestEx(send_this);
if (request_ret)
{
break;
}
} int read_now=send_this;
while (read_now>0)
{
int tag=read_now>4096?4096:read_now; //上传文件的buffer选为4KB
m_file.Read(pFileBuff, tag); pHF->Write(pFileBuff,tag);
read_now=read_now-tag;
} DWORD dwStateCode = 0;
pHF->QueryInfoStatusCode(dwStateCode); if(dwStateCode == HTTP_STATUS_OK)
bResult = TRUE;
pHF->EndRequest(); //这一步总是抛出异常}
catch(CInternetException * pEx)
{
char sz[500] = "";
pEx->GetErrorMessage(sz, 500);
int xxx=GetLastError();
CString str;
str.Format("InternetException occur!\r\n%s error code=%d", sz,xxx);
AfxMessageBox(str);
}
catch(CFileException& fe)
{
CString str;
str.Format("FileException occur!\r\n%d", fe.m_lOsError);
AfxMessageBox(str);
}
catch(...)
{
DWORD dwError = GetLastError();
CString str;
str.Format("Unknow Exception occur!\r\n%d", dwError);
AfxMessageBox(str);
}
}-------以下是我的测试结果--------------
当我客户端只传一个9M的文件时,偶尔会在endrequest这一步抛出异常提示信息“The operation timed out!”,用getlasterror查看错误码为2;不过大部分分块传输完执行endrequest时都是正常的; 当我在客户端同时上传2个9M文件时,两个进程执行到endrequest时都会抛出异常信息“The operation timed out”,错误码还是2!但是虽然有异常信息,提示异常信息的那一块文件却可以发送正常,也就是说服务器那边可以接收到!但也存在部分块传输失败的情况。-------------------------------------------------
1。 请问此处关于endrequest异常的问题怎么解决?
2。 这个项目的HTTP服务器那端的代码是我老板写的,是不是他那边没有处理我这个endrequest请求的模块,导致我这边超时呢?
我发现如果提示超时的话,这条HTTP连接好像并没有立刻关掉,这样就导致我后来的HTTP连接申请会因为WINDOWS系统对同一个HTTP服务器的连接数限制而被阻塞掉,导致后面的数据都无法发送。
大家请指点以下,互相讨论一下!
我查看了MSDN的例子后写了如下函数 ,发送部分采用了sendrequestex()和endrequest函数(),在线程入口函数中的上传部分代码如下:***注:因为是解决endrequest的问题,所以代码只贴上传这一关键部分的代码,
其中一些变量不作说过多说明
CHttpConnection * pHC = NULL;
CHttpFile * pHF = NULL;
CInternetSession cis;
cis.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 9000);
cis.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 3); //重试次数 pHC = cis.GetHttpConnection(strServer, wPort,temp->user_name,temp->user_password); //带“用户名”“密码”的http连接申请while (send_now>0)
{
int send_this=send_now>1048576?1048576:send_now;//判断每一次循环需要发送的数据大小try
{ m_file.Seek((tailnumber)*1048576,CFile::begin);
tailnumber++; //统计分块传输的次数 pHF = pHC->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject); while(1)
{
int request_ret=pHF->SendRequestEx(send_this);
if (request_ret)
{
break;
}
} int read_now=send_this;
while (read_now>0)
{
int tag=read_now>4096?4096:read_now; //上传文件的buffer选为4KB
m_file.Read(pFileBuff, tag); pHF->Write(pFileBuff,tag);
read_now=read_now-tag;
} DWORD dwStateCode = 0;
pHF->QueryInfoStatusCode(dwStateCode); if(dwStateCode == HTTP_STATUS_OK)
bResult = TRUE;
pHF->EndRequest(); //这一步总是抛出异常}
catch(CInternetException * pEx)
{
char sz[500] = "";
pEx->GetErrorMessage(sz, 500);
int xxx=GetLastError();
CString str;
str.Format("InternetException occur!\r\n%s error code=%d", sz,xxx);
AfxMessageBox(str);
}
catch(CFileException& fe)
{
CString str;
str.Format("FileException occur!\r\n%d", fe.m_lOsError);
AfxMessageBox(str);
}
catch(...)
{
DWORD dwError = GetLastError();
CString str;
str.Format("Unknow Exception occur!\r\n%d", dwError);
AfxMessageBox(str);
}
}-------以下是我的测试结果--------------
当我客户端只传一个9M的文件时,偶尔会在endrequest这一步抛出异常提示信息“The operation timed out!”,用getlasterror查看错误码为2;不过大部分分块传输完执行endrequest时都是正常的; 当我在客户端同时上传2个9M文件时,两个进程执行到endrequest时都会抛出异常信息“The operation timed out”,错误码还是2!但是虽然有异常信息,提示异常信息的那一块文件却可以发送正常,也就是说服务器那边可以接收到!但也存在部分块传输失败的情况。-------------------------------------------------
1。 请问此处关于endrequest异常的问题怎么解决?
2。 这个项目的HTTP服务器那端的代码是我老板写的,是不是他那边没有处理我这个endrequest请求的模块,导致我这边超时呢?
我发现如果提示超时的话,这条HTTP连接好像并没有立刻关掉,这样就导致我后来的HTTP连接申请会因为WINDOWS系统对同一个HTTP服务器的连接数限制而被阻塞掉,导致后面的数据都无法发送。
大家请指点以下,互相讨论一下!
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货