我必须通过套接字从Internet下载文件。我写了这段代码,结果有点奇怪。当我编译它并运行它只是创建sample.mp3(它是空的)。如果我用调试器运行它,它会创建文件并填充一点(274 720字节)。我该如何解决? 我正在使用带有mingw32 compilator的Code :: Blocks。
#include <iostream>
#include <winsock2.h>
#include <string>
#include <fstream>
#define DEFAULT_BUFFLEN 1024
using namespace std;
int main()
{
char* host;
char* req;
host = "cs9-5v4.vk.me";
req = "/p18/f854bad2afcb34.mp3?extra=KOpJtWM9maWNBYyDfiQwKFo6p6cZ_EfQz4O_Jzz26anBd9bPXYlqageCjJQe5yNqfnaGAXKtP5jwQYWf1CaTef9dJomPrzya";
string rdyStr;
rdyStr += "GET ";
rdyStr += req;
rdyStr += " HTTP/1.1\nHost: ";
rdyStr += host;
rdyStr += "\n\n";
WSADATA wsaData;
WORD version;
int error;
version = MAKEWORD( 2, 0);
error = WSAStartup( version, &wsaData );
if (error != 0)
{
cout << "There is some error:" << error << endl;
return -1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0)
{
WSACleanup();
cout << "Incorrect winsock version" << endl;
return -2;
}
SOCKET client;
client = socket(AF_INET, SOCK_STREAM, 0);
struct hostent *Host;
Host = gethostbyname( host );
if (Host == NULL)
{
cout << "There is no such host" << endl;
return -3;
}
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = ((struct in_addr *)(Host->h_addr))->s_addr;
if (connect(client, (struct sockaddr *) &sin, sizeof(sin)) == SOCKET_ERROR)
{
cout << "Cant connect to the server" << endl;
return -4;
}
char result[DEFAULT_BUFFLEN];
int recvResult = 1;
int recvBufflen = DEFAULT_BUFFLEN;
int rs = send(client, rdyStr.c_str(), recvBufflen, 0);
rs = shutdown(client, SD_SEND);
ofstream fl;
fl.open("sample.mp3", ios::out | ios::binary);
getchar();
do
{
recvResult = recv(client, result, recvBufflen, 0);
fl.write(result, recvResult);
if (recvResult < 0)
{
cout << "There is some errors with reciecing info" << endl;
return -5;
}
}
while (recvResult > 0);
fl.close();
}
答案 0 :(得分:0)
在之后你已经测试了read()结果为零或负数之前,你不应该调用write()。您可以将循环写为:
while ((recvCount = recv(client, result, recvBufLen, 0)) > 0)
{
fl.write(result, recvResult);
}
然后进行错误测试。注意如果得到否定结果,则应在某处打印WSAGetLastError()值。