我用CSocket编写了一个HTTP下载程序,接收数据大概如下://......
//use CSocket class
//send request...
//......
int recevieSize(1);
while(recevieSize > 0)
{
ZeroMemory(buff, BUFFSIZE + 1);
receviedSize = socket.Receive(buff, BUFFSIZE);
if(receivedSize > 0)
{
//use CFile class
downloadFile.Write(buff, receviedSize);
//some handle...
}
} //some handle...因为CSocket::Receive()函数每次接收的bytes是不确定的,所以每次写入文件的bytes就不同了。
这段代码看上去毫无问题,但是运行过程中,在下载文件时会出现ERROR_INVALID_USER_BUFFER错误,根据MSDN上的解释:“The supplied user buffer is not valid for the requested operation.”
我尝试加大了缓冲区,但是问题依旧。这让我百思不得其解。
后来根据这个stackoverflow上的这个帖子(http://stackoverflow.com/questions/12643441/win-32-writefile-access-viloation-and-error-1784)
我把代码改成这样://......
//use CSocket class
//send request...
//......
int recevieSize(1);
int readSize;
while(recevieSize > 0)
{
ZeroMemory(buff, BUFFSIZE + 1);
//downloadSize是此次任务需要下载的总bytes大小
readSize = downloadSize > BUFFSIZE ? BUFFSIZE : downloadSize;
receviedSize = socket.Receive(buff, BUFFSIZE);
readSize -= receviedSize;
while(readSize && (receviedSize > 0))
{
int rs = socket.Receive(buff + receivedSize, readSize);
if(rs == 0)//connection has been close
break;
else if(rs == SOCKET_ERROR)
{
receviedSize = rs;
break;
}
receivedSize += rs;
readSize -= rs;
}
if(receivedSize > 0)
{
//use CFile class
downloadFile.Write(buff, receviedSize);
//some handle...
}
}
//some handle...这样就保证了每次写入文件的bytes数为BUFFSIZE,运行起来就没有出现ERROR_INVALID_USER_BUFFER了。
但是为什么每次写入相同的bytes数时就没问题而写入不同bytes时就会出错呢?
//use CSocket class
//send request...
//......
int recevieSize(1);
while(recevieSize > 0)
{
ZeroMemory(buff, BUFFSIZE + 1);
receviedSize = socket.Receive(buff, BUFFSIZE);
if(receivedSize > 0)
{
//use CFile class
downloadFile.Write(buff, receviedSize);
//some handle...
}
} //some handle...因为CSocket::Receive()函数每次接收的bytes是不确定的,所以每次写入文件的bytes就不同了。
这段代码看上去毫无问题,但是运行过程中,在下载文件时会出现ERROR_INVALID_USER_BUFFER错误,根据MSDN上的解释:“The supplied user buffer is not valid for the requested operation.”
我尝试加大了缓冲区,但是问题依旧。这让我百思不得其解。
后来根据这个stackoverflow上的这个帖子(http://stackoverflow.com/questions/12643441/win-32-writefile-access-viloation-and-error-1784)
我把代码改成这样://......
//use CSocket class
//send request...
//......
int recevieSize(1);
int readSize;
while(recevieSize > 0)
{
ZeroMemory(buff, BUFFSIZE + 1);
//downloadSize是此次任务需要下载的总bytes大小
readSize = downloadSize > BUFFSIZE ? BUFFSIZE : downloadSize;
receviedSize = socket.Receive(buff, BUFFSIZE);
readSize -= receviedSize;
while(readSize && (receviedSize > 0))
{
int rs = socket.Receive(buff + receivedSize, readSize);
if(rs == 0)//connection has been close
break;
else if(rs == SOCKET_ERROR)
{
receviedSize = rs;
break;
}
receivedSize += rs;
readSize -= rs;
}
if(receivedSize > 0)
{
//use CFile class
downloadFile.Write(buff, receviedSize);
//some handle...
}
}
//some handle...这样就保证了每次写入文件的bytes数为BUFFSIZE,运行起来就没有出现ERROR_INVALID_USER_BUFFER了。
但是为什么每次写入相同的bytes数时就没问题而写入不同bytes时就会出错呢?
而且CSocket::Receive()第二个参数不是指定了接收缓冲区的长度吗?
我设置为BUFFSIZE,那么接收到的数据receviedSize最大也就是BUFFSIZE吧,我写入文件的时候同样也指定为Write函数的第二个参数为receviedSize,那么怎么会超出缓冲区长度呢?
我刚才重新调试监测过,发现receviedSize小于BUFFSIZE也会出现这错误的。
这是为什么呢?
应该是:
receviedSize = socket.Receive(buff, readSize);