Yritän hakea winsockin avulla tiedostoa HTTP serveriltä. Jostain syystä kuitenkin recv epäonnistuu jokainen kerta enkä tiedä mikä on syynä. Keksiikö kukaan mikä tässä mättää :).
EDIT: siis recv palauttaa -1 jolloin Failed: viesti näytetään. ja jos jotain ihmetyttää Client << wsagetlasterror() niin halusin vain nähdä meneekö tiedostoon mitään. Ei :O
private: System::Void onClickUpdate(System::Object^ sender, System::EventArgs^ e) {
bool err = 0; //lopetan funktion tällä..
this->textBox1->Text = L"Connecting to update server";
Application::DoEvents();
while (err == false)
{
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
{
this->textBox1->Text = L"Failed: Could not initialize winsock";
err = true;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
this->textBox1->Text = L"Failed: Socket creation failed";
err = true;
}
struct hostent *host;
if ( (host = gethostbyname("asd.serveri.org")) == NULL)
{
this->textBox1->Text = L"Failed: Failed to resolve hostname";
err = true;
}
SOCKADDR_IN sockaddr;
sockaddr.sin_port = htons(80);
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *) *host->h_addr_list)); //host:n ip käsittääkseni
if (connect(sock, (const SOCKADDR*)(&sockaddr),sizeof(sockaddr)) != 0)
{
this->textBox1->Text = L"Failed: Couldnt connect to server";
err = true;
}
char* freq = "GET /updates/current.swf HTTP/1.0\r\nUser-Agent: AE Updater\r\nAccept: */ *\r\nHost: asd.serveri.org";
//get rivillä tarkoituksella väli / * kohdalla koska koodi värjäytyy väärin muuten
const char* fileRequest = freq;
char *buffer = NULL;
int result = 0;
std::ofstream Client("uusi.swf", std::ios::out);
this->textBox1->Text = L"Succesfully connected to the server";
Application::DoEvents();
send(sock, fileRequest, strlen(fileRequest), 0);
this->textBox1->Text = L"Loading client: please be patient";
Application::DoEvents();
do
{
result = recv(sock, buffer, 2048, MSG_WAITALL); //waitall ei vaikuta ongelmaan
Application::DoEvents();
if (result == 0)
{
Client.close();
this->textBox1->Text = L"Checking if an update is needed...";
Application::DoEvents();
this->textBox1->Text = L"Update completed succesfully";
shutdown(sock, SD_SEND);
closesocket(sock);
Application::DoEvents();
err = true;
}
else if (result < 0)
{
Client << WSAGetLastError();
this->textBox1->Text = L"Failed: Download failed, please restart updater";
Application::DoEvents();
shutdown(sock, SD_SEND);
closesocket(sock);
err = true;
}
else
{
this->textBox1->Text = L"Perskuta tulee dataa!";
Application::DoEvents();
Client << buffer;
buffer = NULL;
}
} while (result > 0);
}
//pakko olla ettei while jatku se on muutenkin vaan errorien havaittemiseen
//while loppuu
WSACleanup(); //jos jotain menee pieleen
Application::DoEvents();
}HTTP-protokollassa viimeisen otsikon jälkeen kuuluu tulla kaksi rivinvaihtoa. Lisäksi otsikko Connection: close ei olisi hassumpi.
"GET /updates/current.swf HTTP/1.0\r\nUser-Agent: AE Updater\r\nAccept: */*\r\nHost: asd.server.org\r\nConnection: close\r\n\r\n"
tuollaisen lähetin ja lopputulos on sama. Apachen access-loki näyttää että pyyntö tuli: "GET /updates/current.swf HTTP/1.0" 200 190025. Eikös 200 ole OK ja tiedoston pitäisi lähteä?
Pitäisihän sieltä joka tapaukessa tulla dataa, nimittäin vastauksen HTTP-otsikot:
HTTP/1.0 404 Not Found Content-type: text/html; charset=UTF-8 Content-Length: 16 Connection: close Date: Tue, 06 Apr 2010 18:03:15 GMT Server: lighttpd/1.4.26 404 - Not Found!
Onneksesi huomasin kuitenkin virheen: et ole varannut puskurille tilaa. Puskurina pitäisi käyttää taulukkoa eikä tyhjää osoitinta.
// Valmis taulukko, koko sizeof-operaattorilla: char buffer[2048]; recv(sock, buffer, sizeof(buffer), 0); // Dynaamisesti sizeof-operaattori ei toimi: char* buffer = new char[2048]; recv(sock, buffer, 2048, 0);
Nyt toimii, kiitos Metabolix!
Aikaisemmin visual C++ heitti jonkun ihan oudon virheen ja sain sen poistumaan vain vaihtamalla char a[]:n pointeriksi, mutta näemmä ongelma on hävinnyt.
Aihe on jo aika vanha, joten et voi enää vastata siihen.