Downloader doesnt get all the data
So i am trying to make a downloader based on http protocol. It works ok on small txt files, but if i try downloading something bigger, lets say a picture, it doesnt get all of the data.
void accel::getfile(int from, int to){
//send GET message
string msg = msg_get(fpath, true, from, to);
int back = send(socketC, (char*)&msg[0], msg.size(), 0);
//recv response
int buffsize = 512; //buffer size. should not be less than 512
string buff(buffsize, 0);//, resp; //buffer, response message
fstream output(fname, ios::out, ios::trunc); //file
bool found = false;
int dld = 0;
do {
//recv msg to buffer
back = recv(socketC, (char*)&buff[0], buffsize, 0);
dld += back;
//buff.insert(back, "\0");
//cout << buff.c_str();
//is the writing of the body started?
if (found){
output.write(buff.c_str(), back);
cout << ".";
}
//if not find where the body starts
else {
int point = buff.find("\r\n\r\n");
if (point != -1){
char *p = (char*)&开发者_运维问答;buff[point+4];
output.write(p, back-point-4);
cout << ".";
found = true;
}
}
} while (back == buffsize);
output.close();
cout << "\nComplete\n";
cout << dld << "bytes downloaded\n";
}
Requests:
string msg_head(string fpath, bool keep_alive){
string msg;
//
msg = "HEAD ";
msg += fpath;
msg += " HTTP/1.0\r\n";
if (keep_alive)
msg += "Connection: keep-alive\r\n\r\n";
else
msg += "Connection: close\r\n\r\n";
return msg;
}
string msg_get(string fpath, bool keep_alive, int from, int to){
string msg;
char number[10];
msg = "GET ";
msg += fpath;
msg += " HTTP/1.0\r\n";
msg += "Range: bytes=";
sprintf(number, "%d", from);
msg += number;
msg += "-";
sprintf(number, "%d", to);
msg += number;
msg += "\r\n";
if (keep_alive)
msg += "Connection: keep-alive\r\n\r\n";
else
msg += "Connection: close\r\n\r\n";
return msg;
}
recv
may not fill the whole buffer if there is not enough data available yet. You should detect the end of the message by one of the means specified in the HTTP protocol.
Your code appears to assume that recv
always returns the maximum amount of data (ie. that it waits for n bytes to appear). recv
may return early if a smaller amount of data is currently available.
Instead, you should continue until either disconnection (when recv
returns 0, or an error such as WSAECONNRESET
) or an expected number of bytes (which you should have once the header is fully received)
精彩评论